<?php

declare(strict_types=1);

namespace App\Tests\Feature\Setting;

use App\Entity\ContentSource;
use App\Tests\Feature\AbstractApiTestCase;
use Symfony\Component\HttpFoundation\Response;
use Zenstruck\Foundry\Test\ResetDatabase;

final class ImportContentSourceTest extends AbstractApiTestCase
{
    use ResetDatabase;

    protected function setUp(): void
    {
        parent::setUp();
    }

    public function testItImportsContentSourcesSuccessfully(): void
    {
        $importData = [
            'contentSources' => [
                [
                    'baseUrl' => 'https://mangadex.org',
                    'chapterUrlFormat' => 'https://mangadex.org/chapter/{id}',
                    'scrapingType' => 'html',
                    'imageSelector' => '.chapter-image img',
                    'nextPageSelector' => '.next-page',
                    'chapterSelector' => '.chapter-list a'
                ],
                [
                    'baseUrl' => 'https://mangakakalot.com',
                    'chapterUrlFormat' => 'https://mangakakalot.com/chapter/{id}',
                    'scrapingType' => 'javascript',
                    'imageSelector' => '.page-image img',
                    'nextPageSelector' => '.next-button',
                    'chapterSelector' => '.chapter-link'
                ]
            ]
        ];

        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => $importData
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);

        // Vérifier que les sources ont été créées en base
        $sources = $this->entityManager->getRepository(ContentSource::class)->findAll();
        $this->assertCount(2, $sources);

        $baseUrls = array_map(fn($source) => $source->getBaseUrl(), $sources);
        $this->assertContains('https://mangadex.org', $baseUrls);
        $this->assertContains('https://mangakakalot.com', $baseUrls);
    }

    public function testItValidatesRequiredFields(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => [
                    [
                        'baseUrl' => '',
                        'chapterUrlFormat' => '',
                        'scrapingType' => ''
                    ]
                ]
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_BAD_REQUEST);
    }

    public function testItValidatesBaseUrlFormat(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => [
                    [
                        'baseUrl' => 'invalid-url',
                        'chapterUrlFormat' => 'https://mangadex.org/chapter/{id}',
                        'scrapingType' => 'html',
                        'imageSelector' => '.image',
                        'nextPageSelector' => '.next',
                        'chapterSelector' => '.chapter'
                    ]
                ]
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);
    }

    public function testItValidatesScrapingType(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => [
                    [
                        'baseUrl' => 'https://mangadex.org',
                        'chapterUrlFormat' => 'https://mangadex.org/chapter/{id}',
                        'scrapingType' => 'invalid-type',
                        'imageSelector' => '.image',
                        'nextPageSelector' => '.next',
                        'chapterSelector' => '.chapter'
                    ]
                ]
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);
    }

    public function testItValidatesContentSourcesArray(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => 'not-an-array'
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_BAD_REQUEST);
    }

    public function testItValidatesNonEmptyContentSources(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => []
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_UNPROCESSABLE_ENTITY);
    }

    public function testItValidatesContentSourcesField(): void
    {
        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'invalidField' => []
            ]
        ]);

        $this->assertResponseStatusCodeSame(Response::HTTP_UNPROCESSABLE_ENTITY);
    }

    public function testItImportsSourcesWithOptionalFields(): void
    {
        $importData = [
            'contentSources' => [
                [
                    'baseUrl' => 'https://simple-source.com',
                    'chapterUrlFormat' => 'https://simple-source.com/chapter/{id}',
                    'scrapingType' => 'html',
                    'imageSelector' => '.simple-image',
                    'nextPageSelector' => '.simple-next',
                    'chapterSelector' => '.simple-chapter'
                ]
            ]
        ];

        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => $importData
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);

        // Vérifier que la source a été créée
        $source = $this->entityManager->getRepository(ContentSource::class)->findOneBy([
            'baseUrl' => 'https://simple-source.com'
        ]);
        $this->assertNotNull($source);
        $this->assertEquals('html', $source->getScrapingType());
        $this->assertEquals('.simple-image', $source->getImageSelector());
        $this->assertEquals('.simple-next', $source->getNextPageSelector());
        $this->assertEquals('.simple-chapter', $source->getChapterSelector());
    }

    public function testItHandlesLargeImport(): void
    {
        $contentSources = [];
        for ($i = 1; $i <= 10; $i++) {
            $contentSources[] = [
                'baseUrl' => "https://source{$i}.com",
                'chapterUrlFormat' => "https://source{$i}.com/chapter/{id}",
                'scrapingType' => 'html',
                'imageSelector' => ".source{$i}-image img",
                'nextPageSelector' => ".source{$i}-next",
                'chapterSelector' => ".source{$i}-chapter a"
            ];
        }

        $response = static::createClient()->request('POST', '/api/content-sources/import', [
            'json' => [
                'contentSources' => $contentSources
            ]
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);

        // Vérifier que toutes les sources ont été créées
        $sources = $this->entityManager->getRepository(ContentSource::class)->findAll();
        $this->assertCount(10, $sources);
    }
}
