<?php

declare(strict_types=1);

namespace App\Controller\Platform;

use App\Entity\Theme;
use App\Form\ThemeType;
use App\Repository\ThemeRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/platform/themes', name: 'platform_theme_')]
#[IsGranted('ROLE_SUPER_ADMIN')]
final class ThemeController extends AbstractController
{
    #[Route('', name: 'index', methods: ['GET'])]
    public function index(ThemeRepository $themeRepository): Response
    {
        return $this->render('platform/theme/index.html.twig', [
            'themes' => $themeRepository->findBy([], ['createdAt' => 'DESC']),
        ]);
    }

    #[Route('/new', name: 'new', methods: ['GET', 'POST'])]
    public function new(Request $request, EntityManagerInterface $entityManager): Response
    {
        $theme = new Theme();

        $form = $this->createForm(ThemeType::class, $theme);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->handlePreviewUpload($theme, $form);
            $entityManager->persist($theme);
            $entityManager->flush();

            $this->addFlash('success', 'Le thème public a été créé avec succès.');

            return $this->redirectToRoute('platform_theme_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->render('platform/theme/new.html.twig', [
            'theme' => $theme,
            'form' => $form,
        ]);
    }

    #[Route('/{id}', name: 'show', requirements: ['id' => '\d+'], methods: ['GET'])]
    public function show(Theme $theme): Response
    {
        return $this->render('platform/theme/show.html.twig', [
            'theme' => $theme,
        ]);
    }

    #[Route('/{id}/edit', name: 'edit', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
    public function edit(Request $request, Theme $theme, EntityManagerInterface $entityManager): Response
    {
        $form = $this->createForm(ThemeType::class, $theme);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->handlePreviewUpload($theme, $form);
            $entityManager->flush();

            $this->addFlash('success', 'Le thème public a été mis à jour.');

            return $this->redirectToRoute('platform_theme_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->render('platform/theme/edit.html.twig', [
            'theme' => $theme,
            'form' => $form,
        ]);
    }

    #[Route('/{id}/delete', name: 'delete', requirements: ['id' => '\d+'], methods: ['POST'])]
    public function delete(Request $request, Theme $theme, EntityManagerInterface $entityManager): Response
    {
        if ($this->isCsrfTokenValid('delete_theme_'.$theme->getId(), (string) $request->request->get('_token'))) {
            $entityManager->remove($theme);
            $entityManager->flush();

            $this->addFlash('success', 'Le thème public a été supprimé.');
        }

        return $this->redirectToRoute('platform_theme_index', [], Response::HTTP_SEE_OTHER);
    }

    /**
     * @param FormInterface<Theme> $form
     */
    private function handlePreviewUpload(Theme $theme, FormInterface $form): void
    {
        $previewFile = $form->get('previewImageFile')->getData();
        if ($previewFile instanceof UploadedFile) {
            $theme->setPreviewImage($this->movePreviewFile($previewFile, $theme));
        }
    }

    private function movePreviewFile(UploadedFile $file, Theme $theme): string
    {
        $projectDir = (string) $this->getParameter('kernel.project_dir');
        $targetDir = $projectDir.'/public/uploads/themes';

        if (!is_dir($targetDir) && !mkdir($targetDir, 0775, true) && !is_dir($targetDir)) {
            throw new \RuntimeException(sprintf('Impossible de créer le dossier de téléversement "%s".', $targetDir));
        }

        $code = $theme->getCode() ?: 'theme';
        $code = preg_replace('/[^a-z0-9_]+/', '_', mb_strtolower($code)) ?: 'theme';
        $code = trim($code, '_') ?: 'theme';

        $extension = $file->guessExtension() ?: $file->getClientOriginalExtension() ?: 'bin';
        $extension = mb_strtolower($extension);
        if ($extension === 'jpeg') {
            $extension = 'jpg';
        }

        $filename = sprintf('%s-apercu-%s.%s', $code, bin2hex(random_bytes(4)), $extension);
        $file->move($targetDir, $filename);

        return 'uploads/themes/'.$filename;
    }
}
