<?php

namespace App\Controller;

use App\Entity\CaseItinerary;
use App\Entity\MemberCase;
use App\Entity\User;
use App\Entity\UserCase;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use DateTime;
use DateTimeZone;
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;
use Symfony\UX\Map\Polyline;

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

    #[Route('/itinerary/report', name: 'app_report_itinerary')]
    public function reportItinerary(Request $request, #[CurrentUser()] ?User $user): Response
    {
        $this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;

        $itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel(
            $user
        );

        $ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
        $cases = [];
        foreach ($ucs as $uc) {
            /** @var UserCase $uc */
            $cases[] = $uc->getMemberCase();
        }

        return $this->render(
            'internal/cases/itinerary/report.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_dashboard'), 'Dashboard'),
                    ],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                    'itineraries' => $itineraries,
                    'cases' => $cases
                ]
            )
        );
    }

    #[Route('/itinerary/map', name: 'app_map_itinerary')]
    public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
    {
        $this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;

        $case = null;
        if ($request->getPayload()->get('caseId')) {
            $case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
        }
        $startDate = (
            $request->getPayload()->get('startDate')
            ?
            new DateTime($request->getPayload()->get('startDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']))
            :
            null);
        $endDate = (
            $request->getPayload()->get('endDate')
            ?
            new DateTime($request->getPayload()->get('endDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']))
            :
            null);
        
        $itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel($user, [
            'case' => $case,
            'from' => $startDate,
            'to' => $endDate,
        ]);

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

        $total_distance = 0;
        $total_duration = new DateTime('00:00:00');

        foreach ($itineraries as $itinerary) {
            /** @var CaseItinerary $itinerary */
            $map->addMarker(new Marker(
                position: new Point(
                    $itinerary->getOriginLocation()->getLat(),
                    $itinerary->getOriginLocation()->getLon()
                ),
                title: $itinerary->getOriginLocation()->getName(),
                infoWindow: new InfoWindow(
                    content: $itinerary->originInfoWindow(),
                )
            ));

            $map->addMarker(new Marker(
                position: new Point(
                    $itinerary->getDestLocation()->getLat(),
                    $itinerary->getDestLocation()->getLon()
                ),
                title: $itinerary->getDestLocation()->getName(),
                infoWindow: new InfoWindow(
                    content: $itinerary->destinationInfoWindow(),
                )
            ));

            /** @var CaseItinerary $itinerary */
            $map->addPolyline(new Polyline(
                points: $itinerary->getGPSPolyLines(),
                infoWindow: new InfoWindow(
                    content: $itinerary->getMemberCase()->getCaseName()
                ),
                extra: ['color' => '#FF0000']
            ));

            $total_distance += $itinerary->getDistance();
            $total_duration->add($itinerary->getDuration());
        }
        $map->fitBoundsToMarkers(true);

        $diff = new DateTime('00:00:00');
        $di = $diff->diff($total_duration);

        return $this->render(
            'internal/cases/itinerary/map.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
                        new Breadcrumb($this->generateUrl('app_report_itinerary'), 'Itinerary Report'),
                    ],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                    'map' => $map,
                    'total_distance' => $total_distance,
                    'total_duration' => $di->format("%H:%i'%s''"),
                ]
            )
        );
    }
}
