<?php

namespace Daylight\Core\Modules\MediaLibrary\Jobs;

use Daylight\Core\Modules\MediaLibrary\Models\Media;
use Daylight\Core\Modules\MediaLibrary\Models\MediaConversion;
use Daylight\Core\Modules\MediaLibrary\Services\MediaUploadService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;

class GenerateMediaConversionJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public Media $media,
        public string $conversionName,
        public array $config
    ) {}

    public function handle(): void
    {
        // Load the original image from storage
        $disk = $this->media->disk;
        $originalPath = $this->media->path;

        if (! Storage::disk($disk)->exists($originalPath)) {
            $this->fail("Original media file not found at path: $originalPath on disk: $disk");

            return;
        }

        $imageContent = Storage::disk($disk)->get($originalPath);
        $image = Image::read($imageContent);

        // Auto-orient and strip EXIF
        $image->orient();

        // Get config
        $width = $this->config['width'] ?? null;
        $height = $this->config['height'] ?? null;
        $quality = $this->config['quality'] ?? 85;
        $format = $this->config['format'] ?? 'jpg';
        $crop = $this->config['crop'] ?? false;

        // Resize image
        if ($width && $height) {
            if ($crop) {
                $image->cover($width, $height);
            } else {
                $image->scale($width, $height);
            }
        } elseif ($width) {
            $image->scale(width: $width);
        } elseif ($height) {
            $image->scale(height: $height);
        }

        // Generate conversion path using the service method
        $conversionPath = MediaUploadService::generateConversionPath($this->media, $this->conversionName, $format);

        // Extract just the filename for the database
        $conversionFileName = basename($conversionPath);

        // Encode with format and quality
        $encodedImage = match ($format) {
            'webp' => $image->toWebp($quality),
            'png' => $image->toPng(),
            'gif' => $image->toGif(),
            default => $image->toJpeg($quality),
        };

        // Save to storage with public visibility
        Storage::disk($disk)->put($conversionPath, (string) $encodedImage, 'public');

        // Get file size
        $size = Storage::disk($disk)->size($conversionPath);

        // Determine mime type
        $mimeType = match ($format) {
            'webp' => 'image/webp',
            'png' => 'image/png',
            'gif' => 'image/gif',
            default => 'image/jpeg',
        };

        // Create or update conversion record
        MediaConversion::updateOrCreate(
            [
                'media_id' => $this->media->id,
                'name' => $this->conversionName,
            ],
            [
                'file_name' => $conversionFileName,
                'disk' => $disk,
                'path' => $conversionPath,
                'size' => $size,
                'mime_type' => $mimeType,
                'width' => $image->width(),
                'height' => $image->height(),
            ]
        );
    }
}
