<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;

class DocumentoStabile extends Model
{
    use HasFactory;

    protected $table = 'documenti_stabili';

    protected $fillable = [
        'stabile_id',
        'nome_file',
        'nome_originale',
        'percorso_file',
        'categoria',
        'tipo_mime',
        'dimensione',
        'descrizione',
        'data_scadenza',
        'tags',
        'pubblico',
        'protetto',
        'password_hash',
        'versione',
        'downloads',
        'ultimo_accesso',
        'caricato_da'
    ];

    protected $casts = [
        'data_scadenza' => 'date',
        'pubblico' => 'boolean',
        'protetto' => 'boolean',
        'downloads' => 'integer',
        'versione' => 'integer',
        'dimensione' => 'integer',
        'ultimo_accesso' => 'datetime'
    ];

    protected $dates = [
        'data_scadenza',
        'ultimo_accesso',
        'created_at',
        'updated_at'
    ];

    /**
     * Relazione con lo stabile
     */
    public function stabile()
    {
        return $this->belongsTo(Stabile::class, 'stabile_id', 'id');
    }

    /**
     * Relazione con l'utente che ha caricato il documento
     */
    public function caricatore()
    {
        return $this->belongsTo(User::class, 'caricato_da', 'id');
    }

    /**
     * Scope: Documenti per categoria
     */
    public function scopePerCategoria($query, $categoria)
    {
        return $query->where('categoria', $categoria);
    }

    /**
     * Scope: Documenti pubblici
     */
    public function scopePubblici($query)
    {
        return $query->where('pubblico', true);
    }

    /**
     * Scope: Documenti in scadenza
     */
    public function scopeInScadenza($query, $giorni = 30)
    {
        return $query->whereNotNull('data_scadenza')
                    ->where('data_scadenza', '<=', now()->addDays($giorni))
                    ->where('data_scadenza', '>=', now());
    }

    /**
     * Scope: Documenti scaduti
     */
    public function scopeScaduti($query)
    {
        return $query->whereNotNull('data_scadenza')
                    ->where('data_scadenza', '<', now());
    }

    /**
     * Accessor: Dimensione formattata
     */
    public function getDimensioneFormattataAttribute()
    {
        $bytes = $this->dimensione;
        if ($bytes === 0) return '0 Bytes';
        
        $k = 1024;
        $sizes = ['Bytes', 'KB', 'MB', 'GB'];
        $i = floor(log($bytes) / log($k));
        
        return number_format($bytes / pow($k, $i), 2) . ' ' . $sizes[$i];
    }

    /**
     * Accessor: Icona del file basata sull'estensione
     */
    public function getIconaFileAttribute()
    {
        $ext = strtolower(pathinfo($this->nome_file, PATHINFO_EXTENSION));
        
        switch ($ext) {
            case 'pdf':
                return 'fa-file-pdf text-danger';
            case 'doc':
            case 'docx':
                return 'fa-file-word text-primary';
            case 'xls':
            case 'xlsx':
                return 'fa-file-excel text-success';
            case 'jpg':
            case 'jpeg':
            case 'png':
            case 'gif':
                return 'fa-file-image text-info';
            default:
                return 'fa-file text-secondary';
        }
    }

    /**
     * Accessor: Stato scadenza
     */
    public function getStatoScadenzaAttribute()
    {
        if (!$this->data_scadenza) {
            return null;
        }

        $oggi = now()->startOfDay();
        $scadenza = $this->data_scadenza->startOfDay();
        $diffGiorni = $oggi->diffInDays($scadenza, false);

        if ($diffGiorni < 0) {
            return ['tipo' => 'scaduto', 'giorni' => abs($diffGiorni), 'classe' => 'danger'];
        } elseif ($diffGiorni <= 7) {
            return ['tipo' => 'in_scadenza_critica', 'giorni' => $diffGiorni, 'classe' => 'danger'];
        } elseif ($diffGiorni <= 30) {
            return ['tipo' => 'in_scadenza', 'giorni' => $diffGiorni, 'classe' => 'warning'];
        }

        return ['tipo' => 'valido', 'giorni' => $diffGiorni, 'classe' => 'success'];
    }

    /**
     * Accessor: URL di download
     */
    public function getUrlDownloadAttribute()
    {
        return route('admin.documenti.download', $this->id);
    }

    /**
     * Accessor: URL di visualizzazione
     */
    public function getUrlViewAttribute()
    {
        return route('admin.documenti.view', $this->id);
    }

    /**
     * Incrementa il contatore di download
     */
    public function incrementaDownload()
    {
        $this->increment('downloads');
        $this->update(['ultimo_accesso' => now()]);
    }

    /**
     * Verifica se il file esiste fisicamente
     */
    public function fileEsiste()
    {
        return Storage::exists($this->percorso_file);
    }

    /**
     * Elimina il file fisico dal storage
     */
    public function eliminaFile()
    {
        if ($this->fileEsiste()) {
            return Storage::delete($this->percorso_file);
        }
        return true;
    }

    /**
     * Array di categorie disponibili
     */
    public static function categorie()
    {
        return [
            'contratti' => 'Contratti',
            'amministrativi' => 'Documenti Amministrativi',
            'tecnici' => 'Documenti Tecnici',
            'catastali' => 'Documenti Catastali',
            'bancari' => 'Documenti Bancari',
            'legali' => 'Documenti Legali',
            'assemblee' => 'Verbali Assemblee',
            'altri' => 'Altri'
        ];
    }

    /**
     * Colori per le categorie
     */
    public static function coloriCategorie()
    {
        return [
            'contratti' => 'primary',
            'amministrativi' => 'info',
            'tecnici' => 'warning',
            'catastali' => 'success',
            'bancari' => 'secondary',
            'legali' => 'danger',
            'assemblee' => 'dark',
            'altri' => 'light'
        ];
    }

    /**
     * Event: Eliminazione del modello
     */
    protected static function boot()
    {
        parent::boot();

        static::deleting(function ($documento) {
            // Elimina il file fisico quando viene eliminato il record
            $documento->eliminaFile();
        });
    }
}
