<?php

namespace App\Models;

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

class TabellaMillesimale extends Model
{
    use HasFactory;

    protected $table = 'tabelle_millesimali';

    protected $fillable = [
        'stabile_id',
        'nome_tabella_millesimale',
        'descrizione',
        'tipo',
        'attiva',
        'data_approvazione',
        'ordinamento',
    ];

    protected $casts = [
        'attiva' => 'boolean',
        'data_approvazione' => 'date',
        'ordinamento' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

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

    /**
     * Relazione con Dettagli Millesimi
     */
    public function dettagli()
    {
        return $this->hasMany(DettaglioTabellaMillesimale::class, 'tabella_millesimale_id');
    }

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

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

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

    /**
     * Calcola il totale millesimi
     */
    public function getTotaleMillesimiAttribute()
    {
        return $this->dettagli()->sum('millesimi');
    }

    /**
     * Verifica se la tabella è bilanciata (totale = 1000)
     */
    public function getIsBilanciataAttribute()
    {
        $totale = $this->totale_millesimi;
        return abs($totale - 1000) < 0.0001; // Tolleranza per errori di precisione
    }

    /**
     * Ottieni lo sbilanciamento della tabella
     */
    public function getSbilanciamentoAttribute()
    {
        return $this->totale_millesimi - 1000;
    }

    /**
     * Conta le unità immobiliari con millesimi assegnati
     */
    public function getUnitaAssegnateAttribute()
    {
        return $this->dettagli()->count();
    }

    /**
     * Accessor per riassunto tabella
     */
    public function getRiassuntoAttribute()
    {
        return [
            'nome' => $this->nome_tabella_millesimale,
            'stabile' => $this->stabile->denominazione ?? 'N/A',
            'unita_assegnate' => $this->unita_assegnate,
            'totale_millesimi' => $this->totale_millesimi,
            'is_bilanciata' => $this->is_bilanciata,
            'sbilanciamento' => $this->sbilanciamento
        ];
    }

    /**
     * Metodo per assegnare millesimi a un'unità immobiliare
     */
    public function assegnaMillesimi($unitaImmobiliareId, $millesimi)
    {
        return DettaglioTabellaMillesimale::updateOrCreate(
            [
                'tabella_millesimale_id' => $this->id,
                'unita_immobiliare_id' => $unitaImmobiliareId
            ],
            [
                'millesimi' => $millesimi
            ]
        );
    }

    /**
     * Metodo per bilanciare automaticamente la tabella
     */
    public function bilancia()
    {
        $dettagli = $this->dettagli;
        $totaleCorrente = $dettagli->sum('millesimi');
        
        if ($totaleCorrente == 0) {
            throw new \InvalidArgumentException('Impossibile bilanciare una tabella senza millesimi assegnati');
        }
        
        $fattoreCorrezione = 1000 / $totaleCorrente;
        
        foreach ($dettagli as $dettaglio) {
            $nuoviMillesimi = round($dettaglio->millesimi * $fattoreCorrezione, 4);
            $dettaglio->update(['millesimi' => $nuoviMillesimi]);
        }
        
        return $this->fresh();
    }

    /**
     * Ottieni tutte le tipologie standard di tabelle millesimali
     */
    public static function getTipologieStandard()
    {
        return [
            'proprieta_generale' => 'Proprietà Generale',
            'scale' => 'Scale',
            'ascensore' => 'Ascensore',
            'riscaldamento' => 'Riscaldamento',
            'acqua_calda' => 'Acqua Calda Sanitaria',
            'condizionamento' => 'Condizionamento',
            'garage' => 'Garage/Autorimesse',
            'giardino' => 'Giardino',
            'piscina' => 'Piscina',
            'personalizzata' => 'Personalizzata'
        ];
    }

    /**
     * Metodo per creare ripartizione spese automatica
     */
    public function creaRipartizioneSpese($voceSpesaId, $importoTotale, $dataRipartizione = null)
    {
        return RipartizioneSpese::create([
            'voce_spesa_id' => $voceSpesaId,
            'stabile_id' => $this->id,
            'tabella_millesimale_id' => $this->tabelleMillesimali()->where('tipo', 'generale')->first()?->id,
            'tipo_ripartizione' => 'millesimale',
            'importo_totale' => $importoTotale,
            'data_ripartizione' => $dataRipartizione ?? now(),
            'stato' => 'bozza',
            'creato_da' => auth()->id() ?? 1
        ]);
    }
}