<?php

declare(strict_types=1);

namespace App\Models;

use App\Enums\AssetDocumentType;
use App\Models\Concerns\Auditable;
use Database\Factories\AssetDocumentFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * One document attached to an asset — a purchase invoice, a PO, a delivery
 * challan, a warranty document, or anything else worth keeping on file. An
 * asset can carry any number of these; see Asset::documents().
 *
 * Immutable once uploaded: there is no "edit", only delete and re-upload.
 * That is what makes the automatic create/delete logging from Auditable
 * enough on its own — there is no update diff to describe.
 *
 * @property int $id
 * @property int $asset_id
 * @property AssetDocumentType $document_type
 * @property string $original_filename
 * @property string $stored_path
 * @property string $mime_type
 * @property int $file_size
 * @property int|null $uploaded_by
 */
class AssetDocument extends Model
{
    /** @use HasFactory<AssetDocumentFactory> */
    use Auditable, HasFactory;

    /** @var list<string> */
    protected $fillable = [
        'asset_id',
        'document_type',
        'original_filename',
        'stored_path',
        'mime_type',
        'file_size',
        'uploaded_by',
    ];

    /**
     * @return BelongsTo<Asset, $this>
     */
    public function asset(): BelongsTo
    {
        return $this->belongsTo(Asset::class);
    }

    /**
     * @return BelongsTo<User, $this>
     */
    public function uploadedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'uploaded_by')->withTrashed();
    }

    /**
     * File size formatted for display (KB below 1 MB, MB above) — the
     * detail page never shows a raw byte count.
     */
    public function humanFileSize(): string
    {
        if ($this->file_size < 1024) {
            return $this->file_size.' B';
        }

        if ($this->file_size < 1024 * 1024) {
            return round($this->file_size / 1024, 1).' KB';
        }

        return round($this->file_size / (1024 * 1024), 1).' MB';
    }

    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'document_type' => AssetDocumentType::class,
            'file_size' => 'integer',
        ];
    }

    protected function auditLabel(): string
    {
        return $this->document_type->label().' — '.$this->asset->asset_tag;
    }
}
