<?php

namespace FluxCms\Core\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Spatie\Translatable\HasTranslations;

class CmsMedia extends Model
{
    use HasTranslations;

    protected $table = 'flux_cms_media';

    protected $fillable = [
        'filename',
        'disk',
        'path',
        'type',
        'mime_type',
        'file_size',
        'original_width',
        'original_height',
        'alt_text',
        'title',
        'collection',
        'conversions',
        'is_published',
        'order',
    ];

    /** @var array<string> */
    public array $translatable = ['alt_text', 'title'];

    protected function casts(): array
    {
        return [
            'alt_text' => 'array',
            'title' => 'array',
            'conversions' => 'array',
            'file_size' => 'integer',
            'original_width' => 'integer',
            'original_height' => 'integer',
            'is_published' => 'boolean',
            'order' => 'integer',
        ];
    }

    public function scopePublished($query)
    {
        return $query->where('is_published', true);
    }

    public function scopeImages($query)
    {
        return $query->where('type', 'image');
    }

    public function scopePdfs($query)
    {
        return $query->where('type', 'pdf');
    }

    public function scopeDocuments($query)
    {
        return $query->whereIn('type', ['pdf', 'document']);
    }

    public function scopeInCollection($query, string $collection)
    {
        return $query->where('collection', $collection);
    }

    public function scopeOrdered($query)
    {
        return $query->orderByDesc('created_at');
    }

    public function getUrl(): string
    {
        return Storage::disk($this->disk)->url($this->path);
    }

    /**
     * Get the URL for a specific conversion profile.
     * Falls back to original if conversion doesn't exist.
     */
    public function getConversionUrl(string $profile): string
    {
        $conversions = $this->conversions ?? [];

        if (isset($conversions[$profile]) && Storage::disk($this->disk)->exists($conversions[$profile])) {
            return Storage::disk($this->disk)->url($conversions[$profile]);
        }

        return $this->getUrl();
    }

    /**
     * Check if a specific conversion exists.
     */
    public function hasConversion(string $profile): bool
    {
        $conversions = $this->conversions ?? [];

        return isset($conversions[$profile])
            && Storage::disk($this->disk)->exists($conversions[$profile]);
    }

    /**
     * @return array<string, string>
     */
    public function getExistingConversions(): array
    {
        return $this->conversions ?? [];
    }

    public function isImage(): bool
    {
        return $this->type === 'image';
    }

    public function isPdf(): bool
    {
        return $this->type === 'pdf';
    }

    public function getHumanFileSize(): string
    {
        $bytes = $this->file_size;
        if ($bytes >= 1048576) {
            return round($bytes / 1048576, 1).' MB';
        }
        if ($bytes >= 1024) {
            return round($bytes / 1024, 0).' KB';
        }

        return $bytes.' B';
    }

    public function getDimensionsLabel(): string
    {
        if ($this->original_width && $this->original_height) {
            return $this->original_width.' × '.$this->original_height;
        }

        return '';
    }
}
