<?php

namespace App\Controller;

use App\Entity\ContentSource;
use App\Form\AppSettingsType;
use App\Form\ContentSourceType;
use App\Manager\AppSettingsManager;
use App\Manager\Toolbar\Factory\ToolbarFactory;
use App\Repository\ContentSourceRepository;
use App\Service\NotificationService;
use App\Service\Scraper\MangaScraperService;
use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class SettingsController extends AbstractController
{
    public function __construct(
        private MangaScraperService    $mangaScraperService,
        private EntityManagerInterface $entityManager,
        private NotificationService $notificationService,
        private ContentSourceRepository $contentSourceRepository
    ) {

    }

    #[Route('/settings', name: 'app_settings')]
    public function index(): Response
    {
        return $this->render('settings/index.html.twig', [
            'controller_name' => 'SettingsController',
        ]);
    }

    #[Route('/settings/general', name: 'app_settings_general')]
    public function general(): Response
    {
        return $this->render('settings/index.html.twig', [
            'controller_name' => 'SettingsController',
        ]);
    }

    #[Route('/settings/folders', name: 'app_settings_folders')]
    public function folders(Request $request, AppSettingsManager $settingsManager): Response
    {
        $currentSettings = $settingsManager->getSettings();

        $form = $this->createForm(AppSettingsType::class, $currentSettings);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $newSettings = $form->getData();
            $settingsManager->updateSettings($newSettings);

            $this->notificationService->sendUpdate(['status' => 'success', 'message' => 'Settings updated successfully.']);
            return $this->json(['success' => true]);
        }

        return $this->render('settings/folders.html.twig', [
            'form' => $form->createView(),
        ]);
    }

    #[Route('/settings/scrappers/list', name: 'app_settings_scrappers_list')]
    public function list(ContentSourceRepository $repository, ToolbarFactory $toolbarFactory): Response
    {
        $contentSources = $repository->findAll();

        return $this->render('settings/scrapper_list.html.twig', [
            'contentSources' => $contentSources,
            'toolbar' => $toolbarFactory->createToolbar('scraper_list')->getGroups(),
        ]);
    }

    #[Route('/settings/scrappers/{id}', name: 'app_settings_scrappers', defaults: ['id' => null])]
    public function scrappers(Request $request, ?ContentSource $contentSource): Response
    {
        $isNew = $contentSource === null;
        $contentSource = $contentSource ?? new ContentSource();

        $form = $this->createForm(ContentSourceType::class, $contentSource);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->entityManager->persist($contentSource);
            $this->entityManager->flush();
            $this->notificationService->sendUpdate(['status' => 'success', 'message' => ($isNew ? 'New scrapper configuration saved' : 'Scrapper configuration updated') . ' successfully.']);
            return $this->redirectToRoute('app_settings_scrappers_list');
        }

        return $this->render('settings/scrappers.html.twig', [
            'form' => $form->createView(),
            'isNew' => $isNew,
        ]);
    }

    /**
     * @throws GuzzleException
     */
    #[Route('/settings/scrappers_test', name: 'app_settings_scrappers_test', methods: ['POST'])]
    public function scrapperTest(Request $request): JsonResponse
    {
        $contentSource = new ContentSource();
        $form = $this->createForm(ContentSourceType::class, $contentSource);
        $form->submit($request->request->all()['content_source']);

        if ($form->isValid()) {
            $mangaSlug = $request->request->get('mangaSlug');
            $chapterNumber = $request->request->get('chapterNumber');

            try {
                $scrapedData = $this->mangaScraperService->testScraping($mangaSlug, $chapterNumber, $contentSource);
            } catch (\Exception $e) {
                $this->notificationService->sendUpdate(['status' => 'error', 'message' => $e->getMessage()]);
                return new JsonResponse([
                    'success' => false,
                    'message' => $e->getMessage(),
                ]);
            }

            return new JsonResponse([
                'success' => true,
                'message' => 'Test successful',
                'data' => $scrapedData
            ]);
        } else {
            return new JsonResponse([
                'success' => false,
                'message' => 'Invalid form submission',
                'errors' => $this->getFormErrors($form)
            ]);
        }
    }

    private function getFormErrors($form): array
    {
        $errors = [];
        foreach ($form->getErrors(true) as $error) {
            $errors[] = $error->getMessage();
        }
        return $errors;
    }

    #[Route('/settings/ui', name: 'app_settings_ui')]
    public function ui(): Response
    {
        return $this->render('settings/index.html.twig', [
            'controller_name' => 'SettingsController',
        ]);
    }

    #[Route('/settings/export_scrappers', name: 'app_settings_scrappers_export', methods: ['GET'])]
    public function exportScrappers(): JsonResponse
    {
        $contentSources = $this->contentSourceRepository->findAll();
        $data = [];

        foreach ($contentSources as $source) {
            $data[] = [
                'baseUrl' => $source->getBaseUrl(),
                'imageSelector' => $source->getImageSelector(),
                'nextPageSelector' => $source->getNextPageSelector(),
                'chapterUrlFormat' => $source->getChapterUrlFormat(),
                'scrapingType' => $source->getScrapingType(),
                'chapterSelector' => $source->getChapterSelector(), //TODO à renommer en chapterListSelector
            ];
        }

        return new JsonResponse($data);
    }

    #[Route('/settings/import_scrappers', name: 'app_settings_scrappers_import', methods: ['POST'])]
    public function importScrappers(Request $request): JsonResponse
    {
        $content = $request->getContent();
        $data = json_decode($content, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Invalid JSON data']);
            return new JsonResponse(['error' => 'Invalid JSON data'], 400);
        }

        foreach ($data as $sourceData) {
            $contentSource = new ContentSource();
            $contentSource->setBaseUrl($sourceData['baseUrl']);
            $contentSource->setImageSelector($sourceData['imageSelector']);
            $contentSource->setNextPageSelector($sourceData['nextPageSelector']);
            $contentSource->setChapterUrlFormat($sourceData['chapterUrlFormat']);
            $contentSource->setScrapingType($sourceData['scrapingType']);

            $this->entityManager->persist($contentSource);
        }

        $this->entityManager->flush();

        return new JsonResponse(['message' => 'Content sources imported successfully']);
    }
}
