<?php

namespace App\Models;

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

class Stabile extends Model
{
    use HasFactory;

    protected $table = 'stabili';

    protected $fillable = [
        'amministratore_id',
        'denominazione',
        'codice_stabile',
        'codice_fiscale',
        'cod_fisc_amministratore',
        'indirizzo',
        'citta',
        'cap',
        'provincia',
        'note',
        'old_id',
        'stato',
        // Nuovi campi dati tecnici
        'anno_costruzione',
        'superficie_totale',
        'numero_piani',
        'numero_ascensori',
        'numero_garage',
        'numero_cantine',
        // Nuovi campi amministratore
        'nome_amministratore',
        'telefono_amministratore',
        'email_amministratore',
        'data_nomina_amministratore',
        // Campi bancari
        'iban_principale',
        'banca_principale',
        'filiale',
        'iban_secondario',
        'banca_secondaria',
        'filiale_secondaria',
        // Amministratore semplificato
        'amministratore_nome',
        'amministratore_email',
        'data_nomina',
        'scadenza_mandato',
        // Dati catastali aggiuntivi
        'mappale',
        'categoria',
        'rendita_catastale',
        'superficie_catastale',
        // JSON fields
        'palazzine_data',
        'locali_servizio',
        // Campi esistenti per compatibilità
        'codice_catastale_comune',
        'foglio',
        'particella',
        'subalterno',
        'sezione',
        'codice_destinatario_sdi',
        'pec_amministratore',
        'pec_condominio',
        'numero_rate_ordinarie',
        'mesi_rate_ordinarie',
        'numero_rate_straordinarie',
        'mesi_rate_straordinarie',
        'numero_unita',
        'tipo_riscaldamento',
        'tipo_acqua',
        'presenza_ascensore',
        'presenza_giardino',
        'presenza_piscina',
        'presenza_garage',
        'codice_interno',
        'registro_anagrafe',
        'documenti_path',
        'attivo',
        'struttura_fisica_json',
        'numero_palazzine',
        'numero_scale_per_palazzina',
        'piano_seminterrato',
        'piano_sottotetto',
        'cortile_giardino',
        'superficie_cortile',
        'riscaldamento_centralizzato',
        'acqua_centralizzata',
        'gas_centralizzato',
        'servizio_portineria',
        'orari_portineria',
        'videocitofono',
        'antenna_tv_centralizzata',
        'internet_condominiale',
        'fondo_riserva_minimo',
        'importo_rata_standard',
        'frequenza_rate',
        // Registro Amministratori (Legge 220/2012 Art.10 c.7)
        'registro_data_nomina',
        'registro_scadenza',
        'registro_delibera',
        'registro_note',
        'giorno_scadenza_rate',
        'iban_condominio',
        'millesimi_generali_calcolati',
        'millesimi_riscaldamento_separati',
        'millesimi_acqua_separati',
        'millesimi_ascensore_separati',
        'configurazione_avanzata',
        'ultima_generazione_unita'
    ];

    protected $casts = [
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'anno_costruzione' => 'integer',
        'numero_piani' => 'integer',
        'numero_unita' => 'integer',
        'superficie_totale' => 'decimal:2',
        'numero_ascensori' => 'integer',
        'numero_garage' => 'integer',
        'numero_rate_ordinarie' => 'integer',
        'numero_rate_straordinarie' => 'integer',
        'presenza_ascensore' => 'boolean',
        'presenza_giardino' => 'boolean',
        'presenza_piscina' => 'boolean',
        // Nuovi cast per campi avanzati
        'struttura_fisica_json' => 'array',
        'palazzine_data' => 'array',
        'locali_servizio' => 'array',
        'numero_palazzine' => 'integer',
        'numero_scale_per_palazzina' => 'integer',
        'piano_seminterrato' => 'boolean',
        'piano_sottotetto' => 'boolean',
        'cortile_giardino' => 'boolean',
        'superficie_cortile' => 'decimal:2',
        'riscaldamento_centralizzato' => 'boolean',
        'acqua_centralizzata' => 'boolean',
        'gas_centralizzato' => 'boolean',
        'servizio_portineria' => 'boolean',
        'videocitofono' => 'boolean',
        'antenna_tv_centralizzata' => 'boolean',
        'internet_condominiale' => 'boolean',
        'fondo_riserva_minimo' => 'decimal:2',
        'importo_rata_standard' => 'decimal:2',
        'giorno_scadenza_rate' => 'integer',
        'millesimi_generali_calcolati' => 'boolean',
        'millesimi_riscaldamento_separati' => 'boolean',
        'millesimi_acqua_separati' => 'boolean',
        'millesimi_ascensore_separati' => 'boolean',
        'configurazione_avanzata' => 'array',
        'ultima_generazione_unita' => 'datetime',
        'presenza_garage' => 'boolean',
        'registro_anagrafe' => 'boolean',
        'attivo' => 'boolean',
        'mesi_rate_ordinarie' => 'array',
        'mesi_rate_straordinarie' => 'array',
        // Nuovi cast per campi aggiunti
        'palazzine_data' => 'array',
        'locali_servizio' => 'array',
        'data_nomina' => 'date',
        'scadenza_mandato' => 'date',
        'rendita_catastale' => 'decimal:2',
        'superficie_catastale' => 'decimal:2',
        // Nuovi cast per i campi aggiunti
        'palazzine_data' => 'array',
        'locali_servizio' => 'array',
        'rendita_catastale' => 'decimal:2',
        'superficie_catastale' => 'decimal:2',
        'data_nomina' => 'date',
        'scadenza_mandato' => 'date'
    ];

    /**
     * Relazione con Amministratore
     */
    public function amministratore()
    {
        return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id');
    }

    /**
     * Relazione con UnitaImmobiliari
     */
    public function unitaImmobiliari()
    {
        return $this->hasMany(UnitaImmobiliare::class, 'stabile_id', 'id');
    }

    /**
     * Relazione con Tickets
     */
    public function tickets()
    {
        return $this->hasMany(Ticket::class, 'stabile_id', 'id');
    }

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

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

    /**
     * Relazione con ChiaviStabili
     */
    public function chiavi()
    {
        return $this->hasMany(ChiaveStabile::class, 'stabile_id');
    }

    /**
     * Relazione con FondiCondominiali
     */
    public function fondi()
    {
        return $this->hasMany(FondoCondominiale::class, 'stabile_id');
    }

    /**
     * Relazione con StrutturaFisicaDettaglio
     */
    public function strutturaFisica()
    {
        return $this->hasMany(StrutturaFisicaDettaglio::class, 'stabile_id');
    }

    /**
     * Relazione con le tabelle millesimali dinamiche
     */
    public function tabelleMillesimali()
    {
        return $this->hasMany(TabellaMillesimale::class, 'stabile_id', 'id');
    }

    /**
     * Relazione con i contatori
     */
    public function contatori()
    {
        return $this->hasMany(Contatore::class, 'stabile_id', 'id');
    }

    /**
     * Relazione con gli algoritmi di ripartizione
     */
    public function algoritmiRipartizione()
    {
        return $this->hasMany(AlgoritmoRipartizione::class, 'stabile_id', 'id');
    }

    /**
     * Contatori condominiali (non legati a unità specifiche)
     */
    public function contatoriCondominiali()
    {
        return $this->hasMany(Contatore::class, 'stabile_id', 'id')->whereNull('unita_immobiliare_id');
    }

    /**
     * Esercizi contabili dello stabile
     */
    public function eserciziContabili()
    {
        return $this->hasMany(EsercizioContabile::class, 'stabile_id', 'id');
    }

    /**
     * Esercizi contabili ordinari
     */
    public function eserciziOrdinari()
    {
        return $this->eserciziContabili()->byTipologia('ordinaria')->ordinatiSequenzialmente();
    }

    /**
     * Esercizi riscaldamento
     */
    public function eserciziRiscaldamento()
    {
        return $this->eserciziContabili()->byTipologia('riscaldamento')->ordinatiSequenzialmente();
    }

    /**
     * Esercizi straordinari
     */
    public function eserciziStraordinari()
    {
        return $this->eserciziContabili()->byTipologia('straordinaria')->ordinatiSequenzialmente();
    }

    /**
     * Tabelle millesimali attive
     */
    public function tabelleMillesimaliAttive()
    {
        return $this->tabelleMillesimali()->attive();
    }

    /**
     * Tabella millesimi di proprietà (principale)
     */
    public function tabellaMillesimiProprieta()
    {
        return $this->hasOne(TabellaMillesimale::class, 'stabile_id', 'id')
                   ->where('tipo_tabella', 'proprieta')
                   ->where('attiva', true);
    }

    /**
     * Documenti dello stabile
     */
    public function documenti()
    {
        return $this->hasMany(DocumentoStabile::class, 'stabile_id', 'id');
    }

    /**
     * Documenti per categoria
     */
    public function documentiPerCategoria($categoria = null)
    {
        $query = $this->documenti()->orderBy('created_at', 'desc');
        
        if ($categoria) {
            $query->where('categoria', $categoria);
        }
        
        return $query;
    }

    /**
     * Documenti pubblici (visibili ai condomini)
     */
    public function documentiPubblici()
    {
        return $this->documenti()->where('pubblico', true);
    }

    /**
     * Documenti in scadenza
     */
    public function documentiInScadenza($giorni = 30)
    {
        return $this->documenti()
                   ->whereNotNull('data_scadenza')
                   ->where('data_scadenza', '<=', now()->addDays($giorni))
                   ->where('data_scadenza', '>=', now());
    }

    /**
     * Costanti per frequenza rate
     */
    public const FREQUENZE_RATE = [
        'mensile' => 'Mensile',
        'bimestrale' => 'Bimestrale', 
        'trimestrale' => 'Trimestrale',
        'quadrimestrale' => 'Quadrimestrale',
        'semestrale' => 'Semestrale',
        'annuale' => 'Annuale'
    ];

    /**
     * Calcola il numero totale di unità immobiliari dalla struttura fisica
     */
    public function calcolaTotaleUnita()
    {
        $totale = 0;
        
        for ($palazzina = 1; $palazzina <= $this->numero_palazzine; $palazzina++) {
            for ($scala = 1; $scala <= $this->numero_scale_per_palazzina; $scala++) {
                // Calcola piani totali (incluso seminterrato e sottotetto)
                $pianiTotali = $this->numero_piani;
                if ($this->piano_seminterrato) $pianiTotali++;
                if ($this->piano_sottotetto) $pianiTotali++;
                
                $totale += $pianiTotali * 2; // Assumiamo 2 unità per piano di default
            }
        }
        
        return $totale;
    }

    /**
     * Genera automaticamente la struttura fisica dettagliata
     */
    public function generaStrutturaFisica()
    {
        $struttura = [];
        
        for ($palazzina = 1; $palazzina <= $this->numero_palazzine; $palazzina++) {
            $nomePalazzina = $this->numero_palazzine > 1 ? chr(64 + $palazzina) : '1';
            
            for ($scala = 1; $scala <= $this->numero_scale_per_palazzina; $scala++) {
                $pianoMin = $this->piano_seminterrato ? -1 : 0;
                $pianoMax = $this->numero_piani;
                if ($this->piano_sottotetto) $pianoMax++;
                
                for ($piano = $pianoMin; $piano <= $pianoMax; $piano++) {
                    $struttura[] = [
                        'palazzina' => $nomePalazzina,
                        'scala' => (string)$scala,
                        'piano' => $piano,
                        'numero_interni' => 2, // Default 2 interni per piano
                        'presenza_ascensore' => $this->presenza_ascensore
                    ];
                }
            }
        }
        
        return $struttura;
    }

    /**
     * Accessor per nome completo stabile
     */
    public function getNomeCompletoAttribute()
    {
        return $this->denominazione . ' - ' . $this->indirizzo . ', ' . $this->citta;
    }

    /**
     * Scope per stabili attivi
     */
    public function scopeAttivi($query)
    {
        return $query->where('stato', 'attivo');
    }

    /**
     * Verifica se lo stabile ha la struttura fisica configurata
     */
    public function hasStrutturaFisicaConfigurata()
    {
        return !empty($this->struttura_fisica_json) || $this->strutturaFisica()->count() > 0;
    }

    /**
     * Accessor per il nome completo dell'indirizzo
     */
    public function getIndirizzoCompletoAttribute()
    {
        return $this->indirizzo . ', ' . $this->cap . ' ' . $this->citta . 
               ($this->provincia ? ' (' . $this->provincia . ')' : '');
    }

    /**
     * Accessor per i dati catastali
     */
    public function getDatiCatastaliAttribute()
    {
        return [
            'codice_comune' => $this->codice_catastale_comune,
            'foglio' => $this->foglio,
            'particella' => $this->particella,
            'subalterno' => $this->subalterno,
            'sezione' => $this->sezione
        ];
    }

    /**
     * Accessor per i dati SDI
     */
    public function getDatiSdiAttribute()
    {
        return [
            'codice_destinatario' => $this->codice_destinatario_sdi,
            'pec_amministratore' => $this->pec_amministratore,
            'pec_condominio' => $this->pec_condominio
        ];
    }

    /**
     * Accessor per la configurazione rate ordinarie
     */
    public function getConfigurazioneRateOrdinarieAttribute()
    {
        return [
            'numero_rate' => $this->numero_rate_ordinarie,
            'mesi' => $this->mesi_rate_ordinarie
        ];
    }

    /**
     * Accessor per la configurazione rate straordinarie
     */
    public function getConfigurazioneRateStraordinarieAttribute()
    {
        return [
            'numero_rate' => $this->numero_rate_straordinarie,
            'mesi' => $this->mesi_rate_straordinarie
        ];
    }

    /**
     * Accessor per le caratteristiche dello stabile
     */
    public function getCaratteristicheAttribute()
    {
        return [
            'anno_costruzione' => $this->anno_costruzione,
            'numero_piani' => $this->numero_piani,
            'numero_unita' => $this->numero_unita,
            'superficie_totale' => $this->superficie_totale,
            'tipo_riscaldamento' => $this->tipo_riscaldamento,
            'tipo_acqua' => $this->tipo_acqua,
            'presenza_ascensore' => $this->presenza_ascensore,
            'numero_ascensori' => $this->numero_ascensori,
            'presenza_giardino' => $this->presenza_giardino,
            'presenza_piscina' => $this->presenza_piscina,
            'presenza_garage' => $this->presenza_garage,
            'numero_garage' => $this->numero_garage
        ];
    }

    /**
     * Metodo per ottenere tutte le anagrafiche associate
     */
    public function getAnagraficheAssociate()
    {
        return AnagraficaCondominiale::whereHas('dirittiReali.unitaImmobiliare', function ($query) {
            $query->where('stabile_id', $this->id);
        })->orWhereHas('contrattiLocazione.unitaImmobiliare', function ($query) {
            $query->where('stabile_id', $this->id);
        })->distinct()->get();
    }

    /**
     * Metodo per ottenere i proprietari dello stabile
     */
    public function getProprietari()
    {
        return AnagraficaCondominiale::whereHas('dirittiReali', function ($query) {
            $query->where('tipo_diritto', 'proprieta')
                  ->whereNull('data_fine')
                  ->whereHas('unitaImmobiliare', function ($q) {
                      $q->where('stabile_id', $this->id);
                  });
        })->distinct()->get();
    }

    /**
     * Metodo per ottenere gli inquilini dello stabile
     */
    public function getInquilini()
    {
        return AnagraficaCondominiale::whereHas('contrattiLocazione', function ($query) {
            $query->where('stato', 'attivo')
                  ->whereDate('data_inizio', '<=', now())
                  ->where(function ($q) {
                      $q->whereNull('data_fine')
                        ->orWhereDate('data_fine', '>=', now());
                  })
                  ->whereHas('unitaImmobiliare', function ($q) {
                      $q->where('stabile_id', $this->id);
                  });
        })->distinct()->get();
    }

    /**
     * Metodo per calcolare il totale millesimi
     */
    public function getTotaleMillesimi($tipo = 'proprieta')
    {
        $campo = 'millesimi_' . $tipo;
        return $this->unitaImmobiliari()->where('attiva', true)->sum($campo);
    }

    /**
     * Metodo per verificare la coerenza dei millesimi
     */
    public function verificaMillesimi($tipo = 'proprieta')
    {
        $totale = $this->getTotaleMillesimi($tipo);
        return abs($totale - 1000) < 0.001; // Tolleranza per errori di arrotondamento
    }

    /**
     * Metodo per ottenere le statistiche dello stabile
     */
    public function getStatistiche()
    {
        $unita = $this->unitaImmobiliari()->where('attiva', true);
        
        return [
            'totale_unita' => $unita->count(),
            'unita_in_locazione' => $unita->whereHas('contrattiLocazione', function ($query) {
                $query->where('stato', 'attivo')
                      ->whereDate('data_inizio', '<=', now())
                      ->where(function ($q) {
                          $q->whereNull('data_fine')
                            ->orWhereDate('data_fine', '>=', now());
                      });
            })->count(),
            'superficie_totale' => $unita->sum('superficie_commerciale'),
            'totale_millesimi_proprieta' => $this->getTotaleMillesimi('proprieta'),
            'totale_proprietari' => $this->getProprietari()->count(),
            'totale_inquilini' => $this->getInquilini()->count()
        ];
    }
}