<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Components\Offer;

use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\AdminBundle\Section\SectionComponentInterface;
use Ferienpass\CoreBundle\Entity\Offer\OfferInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent(template: '@FerienpassAdmin/components/Offer/OfferLocation.html.twig', route: 'live_component_admin')]
class OfferLocation extends AbstractController implements SectionComponentInterface
{
    use ComponentToolsTrait;
    use DefaultActionTrait;

    #[LiveProp]
    public OfferInterface $offer;

    #[LiveProp(writable: true, onUpdated: 'setDirty')]
    public ?string $meetingPoint = null;

    #[LiveProp(writable: true, onUpdated: 'setDirty')]
    public ?string $meetingAddress = null;

    #[LiveProp(writable: true, onUpdated: 'setDirty')]
    public ?float $meetingLat = null;

    #[LiveProp(writable: true, onUpdated: 'setDirty')]
    public ?float $meetingLng = null;

    #[LiveProp]
    public bool $isDirty = false;

    #[LiveProp]
    public array $sections = [];

    #[LiveProp]
    public ?string $section = null;

    #[LiveProp]
    public bool $isReadonly = false;

    public string $message = '';

    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        #[Autowire(env: 'MAPBOX_TOKEN')]
        public string $mapboxToken
    ) {
    }

    public function mount(OfferInterface $offer): void
    {
        $this->offer = $offer;
        $this->meetingPoint = $this->offer->getMeetingPoint();
        $this->meetingAddress = $this->offer->getMeetingAddress();
        $this->meetingLat = null !== $this->offer->getMeetingLat() ? (float) $this->offer->getMeetingLat() : null;
        $this->meetingLng = null !== $this->offer->getMeetingLng() ? (float) $this->offer->getMeetingLng() : null;
    }

    #[LiveAction]
    public function setDirty(): void
    {
        $this->isDirty = true;
    }

    #[LiveAction]
    public function save(#[LiveArg] ?string $nextSection = null, #[LiveArg] ?string $redirect = null): ?Response
    {
        $this->denyAccessUnlessGranted('edit', $this->offer);

        $this->offer->setMeetingPoint($this->meetingPoint);
        $this->offer->setMeetingAddress($this->meetingAddress);
        $this->offer->setMeetingLat(null !== $this->meetingLat ? (float) $this->meetingLat : null);
        $this->offer->setMeetingLng(null !== $this->meetingLng ? (float) $this->meetingLng : null);

        $this->entityManager->flush();

        $this->isDirty = false;

        if ($nextSection || $redirect) {
            $this->addFlash('success', ['type' => 'success', 'title' => 'Daten gespeichert', 'message' => 'Die Änderungen wurden erfolgreich übernommen.']);
        } else {
            $this->message = 'Die Änderungen wurden erfolgreich übernommen.';
        }

        $this->dispatchBrowserEvent('live:saved', ['success' => true]);

        if ($nextSection) {
            return $this->redirectToRoute('admin_offers_edit', ['uuid' => $this->offer->getUuid()->toBase58(), 'section' => $nextSection]);
        }
        if ($redirect) {
            return $this->redirectToRoute($redirect, ['uuid' => $this->offer->getUuid()->toBase58()]);
        }

        return null;
    }

    public static function getSectionName(): string
    {
        return 'location';
    }

    public static function getSectionScope(): string
    {
        return 'offer';
    }
}
