<?php

namespace App\Domain\Scraping\Application\CommandHandler;

use App\Domain\Scraping\Application\Command\CheckAllScrapersHealth;
use App\Domain\Scraping\Application\Command\TestScraperConfiguration;
use App\Domain\Scraping\Domain\Contract\Repository\ContentSourceForHealthCheckInterface;
use App\Domain\Scraping\Domain\Contract\Repository\ContentSourceHealthRepositoryInterface;
use Psr\Log\LoggerInterface;

readonly class CheckAllScrapersHealthHandler
{
    public function __construct(
        private ContentSourceForHealthCheckInterface $contentSourceForHealthCheckRepo,
        private ContentSourceHealthRepositoryInterface $contentSourceHealthRepo,
        private TestScraperConfigurationHandler $testScraperConfigurationHandler,
        private LoggerInterface $logger,
    ) {
    }

    public function handle(CheckAllScrapersHealth $command): void
    {
        $sources = $this->contentSourceForHealthCheckRepo->getAll();

        foreach ($sources as $source) {
            if ($source->testSlug === null || $source->testChapterNumber === null) {
                $this->logger->warning('ContentSource {id} has no test config, skipping health check.', ['id' => $source->id]);
                continue;
            }

            try {
                $this->contentSourceHealthRepo->markAsTesting($source->id);
                $testUrl = str_replace(
                    ['{slug}', '{chapterNumber}'],
                    [$source->testSlug, $source->testChapterNumber],
                    $source->chapterUrlFormat
                );

                $testCommand = new TestScraperConfiguration(
                    baseUrl: $source->baseUrl,
                    chapterUrlFormat: $source->chapterUrlFormat,
                    scrapingType: $source->scrapingType,
                    testUrl: $testUrl,
                    mangaSlug: $source->testSlug,
                    chapterNumber: $source->testChapterNumber,
                    imageSelector: $source->imageSelector,
                    nextPageSelector: $source->nextPageSelector,
                    chapterSelector: $source->chapterSelector,
                );

                $response = $this->testScraperConfigurationHandler->handle($testCommand);

                if ($response->success) {
                    $this->contentSourceHealthRepo->markAsHealthy($source->id, new \DateTimeImmutable());
                } else {
                    $firstError = $response->errors[0]['message'] ?? 'Erreur inconnue';
                    $this->contentSourceHealthRepo->markAsUnhealthy($source->id, new \DateTimeImmutable(), $firstError);
                }
            } catch (\Exception $e) {
                $this->contentSourceHealthRepo->markAsUnhealthy($source->id, new \DateTimeImmutable(), $e->getMessage());
            }
        }
    }
}
