<?php

declare(strict_types=1);

namespace App\Services\Upload;

use App\Services\Images\SquareThumbnailService;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;
use RuntimeException;

final class PreviewService
{
    private ?ImageManager $manager = null;

    public function __construct(private readonly SquareThumbnailService $squareThumbnails)
    {
        try {
            $this->manager = extension_loaded('gd') ? ImageManager::gd() : ImageManager::imagick();
        } catch (\Throwable $e) {
            $this->manager = null;
        }
    }

    public function generateFromImage(string $uploadId, string $sourcePath): array
    {
        if ($this->manager === null) {
            throw new RuntimeException('PreviewService requires Intervention Image.');
        }

        $disk = Storage::disk('local');
        if (! $disk->exists($sourcePath)) {
            return $this->generatePlaceholder($uploadId);
        }

        $absolute = $disk->path($sourcePath);
        $previewPath = "tmp/drafts/{$uploadId}/preview.webp";
        $thumbPath = "tmp/drafts/{$uploadId}/thumb.webp";

        $preview = $this->manager->read($absolute)->scaleDown(1280, 1280);

        $previewEncoded = (string) $preview->encode(new \Intervention\Image\Encoders\WebpEncoder(85));

        $disk->put($previewPath, $previewEncoded);
        $this->squareThumbnails->generateFromPath($absolute, $disk->path($thumbPath), [
            'target_size' => (int) config('uploads.square_thumbnails.preview_size', 320),
            'quality' => (int) config('uploads.square_thumbnails.quality', 82),
            'allow_upscale' => false,
        ]);

        return [
            'preview_path' => $previewPath,
            'thumb_path' => $thumbPath,
        ];
    }

    public function generateFromArchive(string $uploadId, ?string $screenshotPath = null): array
    {
        if ($screenshotPath !== null && Storage::disk('local')->exists($screenshotPath)) {
            return $this->generateFromImage($uploadId, $screenshotPath);
        }

        return $this->generatePlaceholder($uploadId);
    }

    public function generatePlaceholder(string $uploadId): array
    {
        $disk = Storage::disk('local');
        $previewPath = "tmp/drafts/{$uploadId}/preview.webp";
        $thumbPath = "tmp/drafts/{$uploadId}/thumb.webp";

        // 1x1 transparent webp
        $tinyWebp = base64_decode('UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAAAfQ//73v/+BiOh/AAA=');
        $disk->put($previewPath, $tinyWebp ?: '');
        $disk->put($thumbPath, $tinyWebp ?: '');

        return [
            'preview_path' => $previewPath,
            'thumb_path' => $thumbPath,
        ];
    }
}
