<?php

namespace App\Models;

use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class Media extends Model
{
    use HasFactory, Auditable;

    protected $fillable = [
        'name',
        'file_path',
        'disk',
        'type',
        'mime_type',
        'extension',
        'size',
        'width',
        'height',
        'category',
        'is_system',
        'uploaded_by',
        'alt_text',
        'sort_order',
    ];

    protected $casts = [
        'is_system' => 'boolean',
    ];

    public function uploader(): BelongsTo
    {
        return $this->belongsTo(User::class, 'uploaded_by');
    }

    public function usages(): HasMany
    {
        return $this->hasMany(MediaUsage::class);
    }

    public function getUrlAttribute(): string
    {
        if (! filled($this->file_path)) {
            return asset('uploads/placeholders/default-service.jpg');
        }

        if (Str::startsWith($this->file_path, ['http://', 'https://', '//'])) {
            return (string) $this->file_path;
        }

        $disk = $this->disk ?: 'public';

        if ($disk === 'public') {
            return asset('storage/' . ltrim((string) $this->file_path, '/'));
        }

        return Storage::disk($disk)->url($this->file_path);
    }

    public function getPreviewUrlAttribute(): string
    {
        return $this->is_image ? $this->url : asset('uploads/placeholders/default-service.jpg');
    }

    public function getIsImageAttribute(): bool
    {
        if (filled($this->mime_type)) {
            return str_starts_with((string) $this->mime_type, 'image/');
        }

        return in_array(strtolower((string) $this->extension), ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'ico'], true);
    }

    public function getIsServiceAssetAttribute(): bool
    {
        return in_array((string) $this->category, ['service-image', 'service-icon'], true);
    }

    public function getIsOriginalUploadAttribute(): bool
    {
        return $this->is_service_asset && Str::startsWith((string) $this->file_path, 'uploads/media/');
    }

    public function getIsSystemDuplicateAttribute(): bool
    {
        if (! $this->is_service_asset || ! Str::startsWith((string) $this->file_path, 'uploads/system/')) {
            return false;
        }

        return static::query()
            ->where('id', '!=', $this->id)
            ->where('name', $this->name)
            ->where('category', $this->category)
            ->where('file_path', 'like', 'uploads/media/%')
            ->exists();
    }

    public function getMediaGuidanceLabelAttribute(): ?string
    {
        if ($this->is_original_upload) {
            return 'Preferred original upload';
        }

        if ($this->is_system_duplicate) {
            return 'Duplicate seeded asset';
        }

        return null;
    }

    public function getMediaGuidanceTextAttribute(): ?string
    {
        if ($this->is_original_upload) {
            return 'Use this version for services and homepage visuals.';
        }

        if ($this->is_system_duplicate) {
            return 'An earlier uploads/media version already exists. Prefer that one instead.';
        }

        return null;
    }
}
