<?php

namespace App\Controller;

use App\Entity\CommunityResource;
use App\Entity\Messages;
use App\Entity\User;
use App\Form\ResourceFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;

class CommunityResourceController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private array $navLinks = []
    ) {
        $this->navLinks = NavList::LIST;
        $this->navLinks['community_resources'] = NavList::PRESENT_LINK;
    }

    #[Route('/resource/list', name: 'app_community_resource')]
    public function list(#[CurrentUser()] User $user): Response
    {
        $rsc = $this->entityManager->getRepository(CommunityResource::class)->findAll();

        return $this->render(
            'internal/community_resource/list.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb('#', 'Community Resources')
                    ],
                    'resources' => $rsc,
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/resource/map', name: 'app_community_resource_map')]
    public function map(#[CurrentUser()] User $user): Response
    {
        $rcs = $this->entityManager->getRepository(CommunityResource::class)->findAll();

        $map = new Map('default');
        $map->center(new Point($_ENV['MAP_CENTER_LAT'], $_ENV['MAP_CENTER_LON']))
            ->zoom($_ENV['MAP_ZOOM_LEVEL'])
        ;

        foreach ($rcs as $rsc) {
            /** @var CommunityResource $rsc */
            $map->addMarker(new Marker(
                position: new Point($rsc->getLat(), $rsc->getLon()),
                title: $rsc->getName(),
                infoWindow: new InfoWindow(
                    content: $rsc->_toInfoWindow()
                ),
                extra: [
                    'type' => ''
                ]
            ));
        }

        return $this->render(
            'internal/community_resource/map.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'map' => $map,
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
                        new Breadcrumb('#', 'Community Resources')
                    ],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/resource/add', name: 'app_community_resource_add')]
    public function add(#[CurrentUser()] User $user, Request $request): Response
    {
        $form = $this->createForm(ResourceFormType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var CommunityResource $rsc */
            $rsc = $form->getData();

            $res = Libs::getLatLonFromGeoapify("{$rsc->getAddress()}, {$rsc->getCity()}, {$rsc->getState()->value} {$rsc->getZip()} US");

            if (!$res) {
                $this->addFlash('warning', 'Could not retrieve latitude and longitude. Please try again.');
                return $this->redirectToRoute('app_community_resource_add');
            }

            list($lat, $lon) = $res;

            $rsc->setLat($lat);
            $rsc->setLon($lon);

            $this->entityManager->persist($rsc);
            $this->entityManager->flush();

            $this->addFlash('success', 'Resource added successfully');

            return $this->redirectToRoute('app_community_resource');
        }

        return $this->render(
            'internal/community_resource/add.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'form' => $form,
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
                        new Breadcrumb('#', 'Add Resource')
                    ],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );

    }

    #[Route('/resource/edit/{id}', name: 'app_community_resource_edit')]
    public function edit(string $id, #[CurrentUser()] User $user, Request $request): Response
    {
        $rsc = $this->entityManager->getRepository(CommunityResource::class)->find($id);
        $form = $this->createForm(ResourceFormType::class, $rsc);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $res = Libs::getLatLonFromGeoapify("{$rsc->getAddress()}, {$rsc->getCity()}, {$rsc->getState()->value} {$rsc->getZip()} US");

            if (!$res) {
                $this->addFlash('warning', 'Could not retrieve latitude and longitude. Please try again.');
                return $this->redirectToRoute('app_community_resource_edit', ['id' => $id]);
            }

            list($lat, $lon) = $res;

            $rsc->setLat($lat);
            $rsc->setLon($lon);

            $this->entityManager->flush();

            $this->addFlash('success', 'Resource updated successfully');

            return $this->redirectToRoute('app_community_resource');
        }

        return $this->render(
            'internal/community_resource/edit.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'form' => $form,
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
                        new Breadcrumb('#', 'Edit Resource')
                    ],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );

    }

    #[Route('/resource/download/{id}', name: 'app_community_resource_download')]
    public function download(string $id): Response
    {
        /** @var CommunityResource $rsc */
        $rsc = $this->entityManager->getRepository(CommunityResource::class)->find($id);

        if (!$rsc) {
            $this->addFlash('error', 'Resource not found.');
            return $this->redirectToRoute('app_community_resource');
        }

        return new Response($rsc->generateVCard(), 200, [
            'Content-Type' => 'text/vcf',
            'Content-Disposition' => 'attachment; filename="' . str_replace(' ', '', $rsc->getName()) . '.vcf"',
            'Content-Length' => strlen($rsc->generateVCard()),
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
            'Expires' => '0',
            'Pragma' => 'public',
            'Content-Transfer-Encoding' => 'binary'
        ]);
    }
}
