<?php

declare(strict_types=1);

namespace App\Application\Api\Images;

use App\Domain\Media\ImageRepository;
use App\Framework\Attributes\Route;
use App\Framework\Exception\ErrorCode;
use App\Framework\Filesystem\ValueObjects\FilePath;
use App\Framework\Http\Exception\NotFound;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Method;
use App\Framework\Http\Responses\JsonResponse;
use App\Framework\Http\Status;

final readonly class DeleteImageController
{
    public function __construct(
        private ImageRepository $imageRepository
    ) {
    }

    #[Route(path: '/api/images/{ulid}', method: Method::DELETE)]
    public function __invoke(HttpRequest $request): JsonResponse
    {
        $ulid = $request->routeParameters->getString('ulid');

        // Find image by ULID
        $image = $this->imageRepository->findByUlid($ulid);
        if (! $image) {
            throw NotFound::create(
                ErrorCode::ENTITY_NOT_FOUND,
                "Image with ULID {$ulid} not found"
            )->withData(['ulid' => $ulid]);
        }

        // Delete physical files
        $this->deletePhysicalFiles($image->path);

        // Delete from database
        $this->imageRepository->delete($image);

        return new JsonResponse([
            'success' => true,
            'message' => 'Image deleted successfully',
            'ulid' => $ulid,
        ], Status::OK);
    }

    /**
     * Delete physical image files (original and variants)
     */
    private function deletePhysicalFiles(FilePath $imagePath): void
    {
        $storageDirectory = FilePath::cwd()->join('storage/media');

        // Delete original image
        $originalPath = $storageDirectory->join($imagePath->toString());
        if ($originalPath->exists() && $originalPath->isFile()) {
            unlink($originalPath->toString());
        }

        // Delete thumbnail if exists
        $thumbnailPath = $storageDirectory->join('thumbnails')->join($imagePath->toString());
        if ($thumbnailPath->exists() && $thumbnailPath->isFile()) {
            unlink($thumbnailPath->toString());
        }

        // Delete other variants (WebP, AVIF, etc.)
        $this->deleteImageVariants($storageDirectory, $imagePath);
    }

    /**
     * Delete all image variants (WebP, AVIF, different sizes)
     */
    private function deleteImageVariants(FilePath $storageDirectory, FilePath $imagePath): void
    {
        $baseFilename = $imagePath->getBasename();
        $directory = $imagePath->getDirectory();

        // Common variant patterns
        $variantPatterns = [
            'webp/' . $directory . '/' . $baseFilename . '.webp',
            'avif/' . $directory . '/' . $baseFilename . '.avif',
            'variants/' . $directory . '/' . $baseFilename . '_small.jpg',
            'variants/' . $directory . '/' . $baseFilename . '_medium.jpg',
            'variants/' . $directory . '/' . $baseFilename . '_large.jpg',
        ];

        foreach ($variantPatterns as $pattern) {
            $variantPath = $storageDirectory->join($pattern);
            if ($variantPath->exists() && $variantPath->isFile()) {
                unlink($variantPath->toString());
            }
        }
    }
}
