<?php

namespace App\Domain\Manga\Infrastructure\ApiPlatform\Controller;

use App\Domain\Manga\Application\Command\ImportChapter;
use App\Domain\Manga\Application\CommandHandler\ImportChapterHandler;
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
use App\Domain\Manga\Infrastructure\ApiPlatform\Resource\ImportChapterResource;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

#[AsController]
final class ImportChapterController extends AbstractController
{
    public function __construct(
        private readonly ImportChapterHandler $commandHandler
    ) {
    }

    public function __invoke(Request $request): Response
    {
        // Get form parameters
        $mangaId = $request->request->get('mangaId');
        $chapterNumber = $request->request->get('chapterNumber');
        $uploadedFile = $request->files->get('file');

        // Validate required fields
        if (!$mangaId) {
            return $this->json([
                ['propertyPath' => 'mangaId', 'message' => 'mangaId is required']
            ], 422);
        }

        if (!$chapterNumber) {
            return $this->json([
                ['propertyPath' => 'chapterNumber', 'message' => 'chapterNumber is required']
            ], 422);
        }

        if (!$uploadedFile) {
            return $this->json([
                ['propertyPath' => 'file', 'message' => 'Please upload a file']
            ], 422);
        }

        // Validate file
        $errors = $this->validateFile($uploadedFile);
        if (!empty($errors)) {
            return $this->json($errors, 422);
        }

        try {
            // Read file binary content
            $fileBinary = file_get_contents($uploadedFile->getPathname());
            if ($fileBinary === false) {
                return $this->json([
                    ['propertyPath' => 'file', 'message' => 'Failed to read the uploaded file']
                ], 400);
            }

            // Create the command
            $command = new ImportChapter(
                mangaId: $mangaId,
                chapterNumber: (float) $chapterNumber,
                fileBinary: $fileBinary
            );

            // Execute the import
            $this->commandHandler->handle($command);

            return $this->json([
                'message' => 'Chapter imported successfully',
                'mangaId' => $mangaId,
                'chapterNumber' => $chapterNumber
            ], 200);

        } catch (MangaNotFoundException $e) {
            return $this->json([
                'error' => 'Manga not found',
                'details' => $e->getMessage()
            ], 404);

        } catch (ChapterNotFoundException $e) {
            return $this->json([
                'error' => 'Chapter not found',
                'details' => $e->getMessage()
            ], 404);

        } catch (\InvalidArgumentException $e) {
            return $this->json([
                'error' => 'Invalid file',
                'details' => $e->getMessage()
            ], 400);

        } catch (\Exception $e) {
            return $this->json([
                'error' => 'Import failed',
                'details' => $e->getMessage()
            ], 500);
        }
    }

    private function validateFile($uploadedFile): array
    {
        $errors = [];

        // Check if file is valid
        if (!$uploadedFile->isValid()) {
            $errors[] = [
                'propertyPath' => 'file',
                'message' => 'The uploaded file is not valid: ' . $uploadedFile->getErrorMessage()
            ];
            return $errors;
        }

        // Check file size (500MB max)
        $maxSize = 500 * 1024 * 1024; // 500MB in bytes
        if ($uploadedFile->getSize() > $maxSize) {
            $errors[] = [
                'propertyPath' => 'file',
                'message' => 'The uploaded file is too large. Allowed size is 500MB.'
            ];
        }

        // Check file extension
        $allowedExtensions = ['cbz'];
        $extension = strtolower($uploadedFile->getClientOriginalExtension());

        if (!in_array($extension, $allowedExtensions)) {
            $errors[] = [
                'propertyPath' => 'file',
                'message' => 'Please upload a valid CBZ file'
            ];
        }

        return $errors;
    }
}
