<?php

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Controller\Admin;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Admin\PopupType;
use CpCreation\VitiCore\Popup\Model\Popup;
use CpCreation\VitiCore\Popup\Repository\PopupRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/annonces')]
#[IsGranted(new Expression("is_granted('ROLE_ADMIN') or is_granted('ROLE_POPUP')"))]
final class PopupController extends AbstractController
{
    public function __construct(
        private readonly PopupRepository $popupRepository,
    ) {}

    #[Route('', name: 'admin_popup')]
    public function index(Request $request): Response
    {
        $filters = $this->buildFilters($request);
        $popups = $this->popupRepository->findBy([], ['publishedAt' => 'DESC']);
        $now = new \DateTimeImmutable('now');
        $statusById = [];
        $items = [];

        foreach ($popups as $popup) {
            $status = $this->resolvePopupStatus($popup, $now);
            $statusById[$popup->getId()->toString()] = $status;

            if ('all' !== $filters['type'] && $filters['type'] !== ($popup->isPopup() ? 'popup' : 'banner')) {
                continue;
            }

            if ('all' !== $filters['status'] && $filters['status'] !== $status['value']) {
                continue;
            }

            $items[] = $popup;
        }

        return $this->render('@CpCreationVitiCore/admin/popup/index.html.twig', [
            'items' => $items,
            'filters' => $filters,
            'status_by_id' => $statusById,
        ]);
    }

    #[Route('/new', name: 'admin_popup_new')]
    public function new(Request $request): Response
    {
        $popup = new Popup();
        $popup->setPublishedAt(new \DateTime());

        $form = $this->createForm(PopupType::class, $popup);
        $form->handleRequest($request);

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

            $this->popupRepository->save($data);
            $this->addFlash('alert-success', 'L’annonce '.$data->getTitle().' a été ajoutée avec succès');

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

        return $this->render('@CpCreationVitiCore/admin/popup/new.html.twig', [
            'form' => $form->createView(),
        ]);
    }

    #[Route('/{id}/edit', name: 'admin_popup_edit')]
    public function edit(Popup $popup, Request $request): Response
    {
        $form = $this->createForm(PopupType::class, $popup);
        $form->handleRequest($request);

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

            $data->setUpdatedAt(new \DateTimeImmutable());

            $this->popupRepository->save($data);
            $this->addFlash('alert-success', 'L’annonce '.$popup->getTitle().' a été modifiée avec succès.');

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

        return $this->render('@CpCreationVitiCore/admin/popup/edit.html.twig', [
            'item' => $popup,
            'form' => $form->createView(),
        ]);
    }

    #[Route('/{id}/delete', name: 'admin_popup_delete')]
    public function delete(Popup $popup): Response
    {
        $this->popupRepository->delete($popup);
        $this->addFlash('alert-success', 'L’annonce '.$popup->getTitle().' a été supprimée avec succès.');

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

    /**
     * @return array{
     *     type: string,
     *     status: string,
     *     query_parameters: array<string, string>
     * }
     */
    private function buildFilters(Request $request): array
    {
        $type = self::trimToNull($request->query->get('type')) ?? 'all';
        $status = self::trimToNull($request->query->get('status')) ?? 'all';

        if (!\in_array($type, ['all', 'popup', 'banner'], true)) {
            $type = 'all';
        }

        if (!\in_array($status, ['all', 'published', 'unpublished'], true)) {
            $status = 'all';
        }

        return [
            'type' => $type,
            'status' => $status,
            'query_parameters' => array_filter([
                'type' => 'all' !== $type ? $type : null,
                'status' => 'all' !== $status ? $status : null,
            ]),
        ];
    }

    /**
     * @return array{value: string, label: string, color: string}
     */
    private function resolvePopupStatus(Popup $popup, \DateTimeImmutable $now): array
    {
        $publishedAt = $popup->getPublishedAt();
        $unPublishedAt = $popup->getUnPublishedAt();

        $isPublished = !$popup->isDisabled()
            && (null === $publishedAt || $publishedAt <= $now)
            && (null === $unPublishedAt || $unPublishedAt >= $now);

        if ($isPublished) {
            return [
                'value' => 'published',
                'label' => 'Publiée',
                'color' => '#5cb85c',
            ];
        }

        return [
            'value' => 'unpublished',
            'label' => 'Dépubliée',
            'color' => '#d9534f',
        ];
    }

    private static function trimToNull(mixed $value): ?string
    {
        if (!\is_string($value)) {
            return null;
        }

        $value = trim($value);

        return '' === $value ? null : $value;
    }
}
