<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class VoceSpesa extends Model
{
    use HasFactory;

    protected $table = 'voci_spesa';

    protected $fillable = [
        'stabile_id',
        'codice',
        'descrizione',
        'tipo_gestione',
        'categoria',
        'tabella_millesimale_default_id',
        'ritenuta_acconto_default',
        'attiva',
        'ordinamento',
    ];

    protected $casts = [
        'ritenuta_acconto_default' => 'decimal:2',
        'attiva' => 'boolean',
        'ordinamento' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

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

    /**
     * Relazione con Tabella Millesimale Default
     */
    public function tabellaMillesimaleDefault()
    {
        return $this->belongsTo(TabellaMillesimale::class, 'tabella_millesimale_default_id');
    }

    /**
     * Relazione con RipartizioneSpese
     */
    public function ripartizioniSpese()
    {
        return $this->hasMany(RipartizioneSpese::class);
    }

    /**
     * Scope per voci attive
     */
    public function scopeAttive($query)
    {
        return $query->where('attiva', true);
    }

    /**
     * Scope per tipo gestione
     */
    public function scopeTipoGestione($query, $tipo)
    {
        return $query->where('tipo_gestione', $tipo);
    }

    /**
     * Scope ordinato
     */
    public function scopeOrdinato($query)
    {
        return $query->orderBy('ordinamento')->orderBy('descrizione');
    }

    /**
     * Boot del modello per generazione automatica codice
     */
    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($model) {
            if (empty($model->codice)) {
                $model->codice = self::generateUniqueCode($model->stabile_id);
            }
        });
    }

    /**
     * Genera un codice univoco per la voce di spesa
     */
    private static function generateUniqueCode($stabileId)
    {
        do {
            $code = 'VS' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
        } while (self::where('stabile_id', $stabileId)->where('codice', $code)->exists());
        
        return $code;
    }

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

    /**
     * Ottieni tutte le categorie standard
     */
    public static function getCategorieStandard()
    {
        return [
            'manutenzione_ordinaria' => 'Manutenzione Ordinaria',
            'manutenzione_straordinaria' => 'Manutenzione Straordinaria',
            'pulizia' => 'Pulizia',
            'illuminazione' => 'Illuminazione',
            'riscaldamento' => 'Riscaldamento',
            'acqua' => 'Acqua',
            'energia_elettrica' => 'Energia Elettrica',
            'gas' => 'Gas',
            'ascensore' => 'Ascensore',
            'giardino_verde' => 'Giardino e Verde',
            'sicurezza' => 'Sicurezza',
            'amministrazione' => 'Amministrazione',
            'assicurazioni' => 'Assicurazioni',
            'tasse_tributi' => 'Tasse e Tributi',
            'spese_legali' => 'Spese Legali',
            'lavori_miglioramento' => 'Lavori di Miglioramento',
            'altre_spese' => 'Altre Spese'
        ];
    }

    /**
     * Ottieni i tipi di gestione
     */
    public static function getTipiGestione()
    {
        return [
            'ordinaria' => 'Gestione Ordinaria',
            'straordinaria' => 'Gestione Straordinaria',
            'speciale' => 'Gestione Speciale'
        ];
    }

    /**
     * Accessor per descrizione completa
     */
    public function getDescrizioneCompletaAttribute()
    {
        return $this->codice . ' - ' . $this->descrizione;
    }

    /**
     * Accessor per categoria formattata
     */
    public function getCategoriaFormattataAttribute()
    {
        $categorie = self::getCategorieStandard();
        return $categorie[$this->categoria] ?? $this->categoria;
    }

    /**
     * Accessor per riassunto voce
     */
    public function getRiassuntoAttribute()
    {
        return [
            'codice' => $this->codice,
            'descrizione' => $this->descrizione,
            'categoria' => $this->categoria_formattata,
            'tipo_gestione' => $this->tipo_gestione,
            'tabella_default' => $this->tabellaMillesimaleDefault->nome_tabella_millesimale ?? 'Nessuna',
            'ritenuta_default' => $this->ritenuta_acconto_default . '%',
            'attiva' => $this->attiva ? 'Sì' : 'No'
        ];
    }

    /**
     * Metodo per duplicare voce di spesa
     */
    public function duplica($nuovaDescrizione = null)
    {
        $nuovaVoce = $this->replicate();
        $nuovaVoce->codice = null; // Verrà rigenerato automaticamente
        $nuovaVoce->descrizione = $nuovaDescrizione ?? ($this->descrizione . ' (Copia)');
        $nuovaVoce->save();
        
        return $nuovaVoce;
    }

    /**
     * Scope per ricerca testuale
     */
    public function scopeRicerca($query, $termine)
    {
        return $query->where(function($q) use ($termine) {
            $q->where('codice', 'LIKE', "%{$termine}%")
              ->orWhere('descrizione', 'LIKE', "%{$termine}%")
              ->orWhere('categoria', 'LIKE', "%{$termine}%");
        });
    }

    /**
     * Metodo per ottenere ripartizioni spese che utilizzano questa voce
     */
    public function getRipartizioniSpese()
    {
        return $this->ripartizioniSpese()
            ->with(['stabile', 'tabellaMillesimale', 'dettagli'])
            ->orderBy('data_ripartizione', 'desc')
            ->get();
    }
}