<?php

namespace App\MessageHandler;

use App\Entity\ContentSource;
use App\Message\DownloadChapter;
use App\Repository\ChapterRepository;
use App\Repository\ContentSourceRepository;
use App\Service\NotificationService;
use App\Service\Scraper\MangaScraperService;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
readonly class DownloadChapterHandler
{
    public function __construct(
        private ChapterRepository $chapterRepository,
        private MangaScraperService $mangaScraperService,
        private NotificationService $notificationService,
        private ContentSourceRepository $contentSourceRepository
    ) {
    }

    /**
     * @throws \Exception
     */
    public function __invoke(DownloadChapter $message): void
    {
        $chapter = $this->chapterRepository->find($message->getChapterId());
        if (!$chapter) {
            $this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Chapter not found.']);
            throw new BadRequestHttpException('Chapter not found');
        } elseif (null !== $chapter->getCbzPath()) {
            $this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Chapter already scraped.']);
            throw new BadRequestHttpException('Chapter already downloaded');
        }

        $manga = $chapter->getManga();
        $preferredSources = $manga->getPreferredSources()->toArray();
        $allSources = $this->contentSourceRepository->findAll();

        $filteredSources = array_udiff($allSources, $preferredSources, function ($a, $b) {
            return $a->getId() - $b->getId();
        });

        $sources = array_merge($preferredSources, $filteredSources);

        if (count($preferredSources) > 0) {
            $sources = $preferredSources;
        } else {
            $sources = $allSources;
        }

        // $sources[] =
        //     (new ContentSource())
        //         ->setBaseUrl('https://api.mangadex.org/')
        //         ->setImageSelector('img')
        //         ->setChapterUrlFormat('at-home/server/%s')
        //         ->setScrapingType('mangadex');

        //            (new ContentSource())
        //                ->setBaseUrl('https://lelscans.net')
        //                ->setImageSelector('#image img')
        //                ->setChapterUrlFormat('https://lelscans.net/scan-%s/%s')
        //                ->setNextPageSelector('a[title="Suivant"]')
        //                ->setScrapingType('html'),
        //            (new ContentSource())
        //                ->setBaseUrl('https://darkscans.net/')
        //                ->setImageSelector('.reading-content img')
        //                ->setChapterUrlFormat('https://darkscans.net/mangas/%s/chapter-%s/')
        //                ->setNextPageSelector(null)
        //                ->setScrapingType('html')

        $scrapedSuccessfully = false;

        foreach ($sources as $source) {
            try {
                $this->mangaScraperService->scrapeChapter($chapter, $source);
                $scrapedSuccessfully = true;
                break;
            } catch (\Exception $e) {
                $this->notificationService->sendUpdate([
                    'status' => 'warning',
                    'message' => 'An error occurred while scraping with source: '.$source->getBaseUrl().'. Trying next source...',
                ]);
            } catch (GuzzleException $e) {

            }
        }

        if (!$scrapedSuccessfully) {
            $this->notificationService->sendUpdate([
                'status' => 'error',
                'message' => 'All sources failed to scrape the chapter '.$chapter->getManga()->getTitle().' '.$chapter->getNumber().'.',
            ]);
            throw new \Exception('All sources failed to scrape the chapter '.$chapter->getManga()->getTitle().' '.$chapter->getNumber().'.');
        }

        $this->notificationService->sendUpdate(['status' => 'success', 'message' => 'Chapter scraped successfully.']);
    }
}
