<?php

namespace App\Models;

use App\Traits\Uuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;

class Document extends Model
{
    use HasFactory;
    use SoftDeletes;
    use Uuid;

    protected $fillable = [
        'uuid',
        'name',
        'description',
        'user_id',
        'disk',
        'path',
        'file_name',
        'original_name',
        'extension',
        'mime_type',
        'size',
        'checksum',
        'is_public',
        'preview_path',
        'preview_mime',
        'preview_generated_at',
        'template_id',
        'template_version',
    ];

    protected $casts = [
        'is_public' => 'boolean',
        'size' => 'integer',
        'preview_generated_at' => 'datetime',
    ];

    protected $appends = [];

    public function documentable(): MorphTo
    {
        return $this->morphTo();
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    // No direct public URL exposure; serve via controller stream

    protected static function booted(): void
    {
        static::deleting(function (Document $doc) {
            // Only delete files on force delete to keep data when soft-deleted
            if (method_exists($doc, 'isForceDeleting') && $doc->isForceDeleting()) {
                try {
                    if ($doc->path) {
                        $disk = $doc->disk ?: 'public';
                        Storage::disk($disk)->delete($doc->path);
                    }
                } catch (\Throwable $e) {
                    // swallow; avoid failing delete due to storage issue
                }

                try {
                    if ($doc->preview_path) {
                        $previewDisk = config('files.preview_disk', 'public');
                        Storage::disk($previewDisk)->delete($doc->preview_path);
                    }
                } catch (\Throwable $e) {
                    // swallow
                }
            }
        });
    }

    /**
     * Include soft-deleted documents when resolving by route key (e.g. {document:uuid}).
     */
    public function resolveRouteBinding($value, $field = null)
    {
        // Always include trashed so deep-linking to older documents works
        return static::withTrashed()
            ->where($field ?? $this->getRouteKeyName(), $value)
            ->firstOrFail();
    }
}
