<?php

namespace App\Domain\Website\Services;

use App\Domain\Website\Enums\MediaCollection;
use App\Domain\Website\Models\Media;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class MediaService
{
    public function upload(
        UploadedFile $file,
        MediaCollection $collection,
        ?string $mediableType = null,
        ?int $mediableId = null,
    ): Media {
        $academy = app('current_academy');
        $dimensions = $this->getImageDimensions($file);

        $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();
        $path = "website/{$academy->id}/{$collection->value}/{$filename}";

        Storage::disk('public')->put($path, file_get_contents($file->getRealPath()));

        return Media::create([
            'academy_id' => $academy->id,
            'collection' => $collection,
            'original_filename' => $file->getClientOriginalName(),
            'disk_path' => $path,
            'mime_type' => $file->getMimeType(),
            'width' => $dimensions['width'],
            'height' => $dimensions['height'],
            'file_size' => $file->getSize(),
            'mediable_type' => $mediableType,
            'mediable_id' => $mediableId,
        ]);
    }

    public function delete(Media $media): void
    {
        if (Storage::disk('public')->exists($media->disk_path)) {
            Storage::disk('public')->delete($media->disk_path);
        }
        $media->delete();
    }

    public function replace(Media $media, UploadedFile $file): Media
    {
        if (Storage::disk('public')->exists($media->disk_path)) {
            Storage::disk('public')->delete($media->disk_path);
        }

        $dimensions = $this->getImageDimensions($file);
        $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();
        $academy = app('current_academy');
        $path = "website/{$academy->id}/{$media->collection->value}/{$filename}";

        Storage::disk('public')->put($path, file_get_contents($file->getRealPath()));

        $media->update([
            'original_filename' => $file->getClientOriginalName(),
            'disk_path' => $path,
            'mime_type' => $file->getMimeType(),
            'width' => $dimensions['width'],
            'height' => $dimensions['height'],
            'file_size' => $file->getSize(),
        ]);

        return $media->fresh();
    }

    public function getForCollection(MediaCollection $collection, ?string $mediableType = null, ?int $mediableId = null)
    {
        $query = Media::where('collection', $collection);

        if ($mediableType && $mediableId) {
            $query->where('mediable_type', $mediableType)
                ->where('mediable_id', $mediableId);
        }

        return $query->orderBy('sort_order')->get();
    }

    public function updateSortOrder(array $orderedIds): void
    {
        foreach ($orderedIds as $index => $id) {
            Media::where('id', $id)->update(['sort_order' => $index]);
        }
    }

    private function getImageDimensions(UploadedFile $file): array
    {
        $imageInfo = @getimagesize($file->getRealPath());
        if ($imageInfo) {
            return ['width' => $imageInfo[0], 'height' => $imageInfo[1]];
        }
        return ['width' => 0, 'height' => 0];
    }

    public function getQualityLevel(UploadedFile $file, MediaCollection $collection): string
    {
        $dimensions = $this->getImageDimensions($file);
        $required = $collection->dimensions();

        $widthRatio = $dimensions['width'] / $required['width'];
        $heightRatio = $dimensions['height'] / $required['height'];
        $ratio = min($widthRatio, $heightRatio);

        if ($ratio >= 1.0) {
            return 'excellent';
        }
        if ($ratio >= 0.75) {
            return 'acceptable';
        }
        return 'too_small';
    }
}
