<?php

namespace App\Models;

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

class UnitaImmobiliare extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'unita_immobiliari';

    protected $fillable = [
        'stabile_id',
        'tipo_utilizzo_id',
        'numero_interno',
        'palazzina',
        'piano',
        'scala',
        'codice_interno',
        'codice_catastale',
        'foglio',
        'particella',
        'subalterno',
        'categoria',
        'classe',
        'consistenza',
        'rendita_catastale',
        'superficie_catastale',
        'superficie_commerciale',
        'millesimi_proprieta',
        'millesimi_riscaldamento',
        'millesimi_ascensore',
        'millesimi_scale',
        'millesimi_pulizie',
        'millesimi_acqua',
        'millesimi_custom_1',
        'millesimi_custom_2',
        'millesimi_custom_3',
        'nome_custom_1',
        'nome_custom_2',
        'nome_custom_3',
        'stato',
        'data_acquisto',
        'valore_acquisto',
        'note',
        'documenti_path',
        'attiva',
        // Campi legacy per compatibilità
        'interno',
        'fabbricato',
        'categoria_catastale',
        'superficie',
        'vani',
        'indirizzo',
        // Nuovi campi avanzati
        'superficie_calpestabile',
        'superficie_balconi',
        'superficie_terrazzi',
        'numero_vani',
        'numero_bagni',
        'numero_balconi',
        'classe_energetica',
        'anno_costruzione',
        'anno_ristrutturazione',
        'stato_conservazione',
        'necessita_lavori',
        'note_tecniche',
        'struttura_fisica_id',
        'calcolo_automatico_millesimi',
        'notifiche_subentri',
        'created_by',
        'updated_by'
    ];

    protected $casts = [
        'data_acquisto' => 'date',
        'valore_acquisto' => 'decimal:2',
        'rendita_catastale' => 'decimal:2',
        'superficie_catastale' => 'decimal:2',
        'superficie_commerciale' => 'decimal:2',
        'millesimi_proprieta' => 'decimal:6',
        'millesimi_riscaldamento' => 'decimal:6',
        'millesimi_ascensore' => 'decimal:6',
        'millesimi_scale' => 'decimal:6',
        'millesimi_pulizie' => 'decimal:6',
        'millesimi_acqua' => 'decimal:6',
        'millesimi_custom_1' => 'decimal:6',
        'millesimi_custom_2' => 'decimal:6',
        'millesimi_custom_3' => 'decimal:6',
        'attiva' => 'boolean',
        // Legacy casts
        'superficie' => 'decimal:2',
        'vani' => 'decimal:2',
        // Advanced casts
        'superficie_calpestabile' => 'decimal:2',
        'superficie_balconi' => 'decimal:2',
        'superficie_terrazzi' => 'decimal:2',
        'numero_vani' => 'integer',
        'numero_bagni' => 'integer', 
        'numero_balconi' => 'integer',
        'anno_costruzione' => 'integer',
        'anno_ristrutturazione' => 'integer',
        'necessita_lavori' => 'boolean',
        'calcolo_automatico_millesimi' => 'boolean',
        'notifiche_subentri' => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

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

    /**
     * Relazione con il tipo di utilizzo
     */
    public function tipoUtilizzo()
    {
        return $this->belongsTo(TipoUtilizzo::class);
    }

    /**
     * Relazione con i diritti reali
     */
    public function dirittiReali()
    {
        return $this->hasMany(DirittoReale::class);
    }

    /**
     * Relazione con i contratti di locazione
     */
    public function contrattiLocazione()
    {
        return $this->hasMany(ContrattoLocazione::class);
    }

    /**
     * Relazione con le ripartizioni spese inquilini
     */
    public function ripartizioniSpese()
    {
        return $this->hasMany(RipartizioneSpeseInquilini::class);
    }

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

    /**
     * Relazione con Proprietà (legacy)
     */
    public function proprieta()
    {
        return $this->hasMany(Proprieta::class, 'unita_immobiliare_id', 'id');
    }

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

    /**
     * Relazione con Rate
     */
    public function rate()
    {
        return $this->hasMany(Rata::class);
    }

    /**
     * Rate attive (emesse o parzialmente pagate)
     */
    public function rateAttive()
    {
        return $this->hasMany(Rata::class)->whereIn('stato', ['emessa', 'parzialmente_pagata', 'scaduta']);
    }

    /**
     * Rate scadute
     */
    public function rateScadute()
    {
        return $this->hasMany(Rata::class)->scadute();
    }

    // === NUOVE RELAZIONI AVANZATE ===

    /**
     * Relazione con i subentri
     */
    public function subentri()
    {
        return $this->hasMany(SubentroUnita::class, 'unita_immobiliare_id', 'id')->orderBy('data_subentro', 'desc');
    }

    /**
     * Ultimo subentro
     */
    public function ultimoSubentro()
    {
        return $this->hasOne(SubentroUnita::class, 'unita_immobiliare_id', 'id')->latest('data_subentro');
    }

    /**
     * Relazione con la composizione dell'unità
     */
    public function composizione()
    {
        return $this->hasMany(ComposizioneUnita::class, 'unita_immobiliare_id', 'id');
    }

    /**
     * Relazione con le ripartizioni spese specifiche
     */
    public function ripartizioniSpeseSpecifiche()
    {
        return $this->hasMany(RipartizioneSpese::class, 'unita_immobiliare_id', 'id');
    }

    /**
     * Relazione con la struttura fisica dettagliata
     */
    public function strutturaFisica()
    {
        return $this->belongsTo(StrutturaFisicaDettaglio::class, 'struttura_fisica_id', 'id');
    }

    /**
     * Relazione con l'utente che ha creato il record
     */
    public function createdBy()
    {
        return $this->belongsTo(User::class, 'created_by', 'id');
    }

    /**
     * Relazione con l'utente che ha aggiornato il record
     */
    public function updatedBy()
    {
        return $this->belongsTo(User::class, 'updated_by', 'id');
    }

    /**
     * Accessor per il nome completo dell'unità
     */
    public function getNomeCompletoAttribute()
    {
        $nome = '';
        
        if ($this->palazzina) {
            $nome .= "Palazzina {$this->palazzina} - ";
        }
        
        if ($this->scala) {
            $nome .= "Scala {$this->scala} - ";
        }
        
        if ($this->piano) {
            $nome .= "Piano {$this->piano} - ";
        }
        
        $numeroInterno = $this->numero_interno ?: $this->interno;
        $nome .= "Interno {$numeroInterno}";
        
        return $nome;
    }

    /**
     * Accessor per i dati catastali
     */
    public function getDatiCatastaliAttribute()
    {
        return [
            'foglio' => $this->foglio,
            'particella' => $this->particella,
            'subalterno' => $this->subalterno,
            'categoria' => $this->categoria ?: $this->categoria_catastale,
            'classe' => $this->classe,
            'consistenza' => $this->consistenza,
            'rendita' => $this->rendita_catastale
        ];
    }

    /**
     * Accessor per tutti i millesimi
     */
    public function getMillesimiAttribute()
    {
        return [
            'proprieta' => $this->millesimi_proprieta,
            'riscaldamento' => $this->millesimi_riscaldamento,
            'ascensore' => $this->millesimi_ascensore,
            'scale' => $this->millesimi_scale,
            'acqua' => $this->millesimi_acqua,
            'custom_1' => $this->millesimi_custom_1,
            'custom_2' => $this->millesimi_custom_2,
            'custom_3' => $this->millesimi_custom_3
        ];
    }

    /**
     * Metodo per ottenere i proprietari attuali
     */
    public function getProprietariAttuali()
    {
        return $this->dirittiReali()
            ->where('tipo_diritto', 'proprieta')
            ->whereNull('data_fine')
            ->with('anagraficaCondominiale')
            ->get();
    }

    /**
     * Metodo per ottenere gli inquilini attuali
     */
    public function getInquiliniAttuali()
    {
        return $this->contrattiLocazione()
            ->where('stato', 'attivo')
            ->whereDate('data_inizio', '<=', now())
            ->where(function ($query) {
                $query->whereNull('data_fine')
                      ->orWhereDate('data_fine', '>=', now());
            })
            ->with('anagraficaCondominiale')
            ->get();
    }

    /**
     * Metodo per verificare se l'unità è in locazione
     */
    public function isInLocazione()
    {
        return $this->contrattiLocazione()
            ->where('stato', 'attivo')
            ->whereDate('data_inizio', '<=', now())
            ->where(function ($query) {
                $query->whereNull('data_fine')
                      ->orWhereDate('data_fine', '>=', now());
            })
            ->exists();
    }

    /**
     * Metodo per ottenere la ripartizione spese attuale
     */
    public function getRipartizioneSpese()
    {
        return $this->ripartizioniSpese()
            ->whereDate('data_inizio', '<=', now())
            ->where(function ($query) {
                $query->whereNull('data_fine')
                      ->orWhereDate('data_fine', '>=', now());
            })
            ->first();
    }

    /**
     * Accessor per identificazione completa dell'unità (legacy)
     */
    public function getIdentificazioneCompiletaAttribute()
    {
        $parts = [];
        if ($this->fabbricato) $parts[] = 'Fabb. ' . $this->fabbricato;
        if ($this->scala) $parts[] = 'Scala ' . $this->scala;
        if ($this->piano) $parts[] = 'Piano ' . $this->piano;
        if ($this->interno || $this->numero_interno) {
            $interno = $this->numero_interno ?: $this->interno;
            $parts[] = 'Int. ' . $interno;
        }
        return implode(', ', $parts) ?: 'N/A';
    }

    /**
     * Accessor per l'indirizzo completo
     */
    public function getIndirizzoCompletoAttribute()
    {
        return $this->indirizzo ?: $this->stabile->indirizzo_completo;
    }

    // === METODI AVANZATI ===

    /**
     * Ottieni il proprietario attuale
     */
    public function proprietarioAttuale()
    {
        return $this->soggetti()
                   ->wherePivot('tipo_diritto', 'proprietà')
                   ->wherePivot('data_fine', null)
                   ->first();
    }

    /**
     * Calcola automaticamente i millesimi
     */
    public function calcolaMillesimiAutomatici(): array
    {
        if (!$this->calcolo_automatico_millesimi) {
            return [];
        }

        $totaleStabile = $this->stabile->unita()->sum('superficie_commerciale');
        if ($totaleStabile <= 0) {
            return [];
        }

        $coefficiente = $this->superficie_commerciale / $totaleStabile * 1000;

        return [
            'millesimi_proprieta' => round($coefficiente, 4),
            'millesimi_riscaldamento' => $this->calcolaMillesimiRiscaldamento(),
            'millesimi_ascensore' => $this->calcolaMillesimiAscensore(),
            'millesimi_scale' => $this->calcolaMillesimiScale(),
            'millesimi_pulizie' => round($coefficiente, 4), // Stesso di proprietà di default
        ];
    }

    private function calcolaMillesimiRiscaldamento(): float
    {
        // Calcolo basato su superficie + coefficienti piano/esposizione
        $base = $this->superficie_commerciale ?: 0;
        $coefficientePiano = $this->getCoefficientePiano();
        $coefficienteEsposizione = $this->getCoefficieneEsposizione();
        
        $totaleRiscaldamento = $this->stabile->getTotaleMillesimiRiscaldamento();
        if ($totaleRiscaldamento <= 0) return 0;
        
        return round($base * $coefficientePiano * $coefficienteEsposizione / $totaleRiscaldamento * 1000, 4);
    }

    private function calcolaMillesimiAscensore(): float
    {
        if ($this->piano <= 0) {
            return 0; // Piano terra e seminterrati non pagano ascensore
        }
        
        $coefficientePiano = max(1, $this->piano * 0.15 + 0.85); // Crescente per piano
        $totaleAscensore = $this->stabile->getTotaleMillesimiAscensore();
        if ($totaleAscensore <= 0) return 0;
        
        return round(($this->superficie_commerciale ?: 0) * $coefficientePiano / $totaleAscensore * 1000, 4);
    }

    private function calcolaMillesimiScale(): float
    {
        $base = $this->superficie_commerciale ?: 0;
        $totaleScale = $this->stabile->getTotaleMillesimiScale();
        if ($totaleScale <= 0) return 0;
        
        if ($this->piano <= 0) {
            return round($base * 0.5 / $totaleScale * 1000, 4);
        }
        
        return round($base / $totaleScale * 1000, 4);
    }

    private function getCoefficientePiano(): float
    {
        // Coefficiente per piano (piano terra = 1.0, aumenta con l'altezza)
        return max(0.8, 1.0 + ($this->piano * 0.1));
    }

    private function getCoefficieneEsposizione(): float
    {
        // Placeholder per coefficiente esposizione - implementare logica specifica
        return 1.0;
    }

    /**
     * Badge color per stato conservazione
     */
    public function getStatoBadgeColor(): string
    {
        return match($this->stato_conservazione) {
            'ottimo' => 'success',
            'buono' => 'info',
            'discreto' => 'warning',
            'cattivo' => 'danger',
            default => 'secondary'
        };
    }

    /**
     * Genera un subentro automatico
     */
    public function generaSubentroAutomatico(Soggetto $nuovoSoggetto, array $datiSubentro): SubentroUnita
    {
        $proprietarioAttuale = $this->proprietarioAttuale();
        
        return $this->subentri()->create([
            'soggetto_precedente_id' => $proprietarioAttuale?->id,
            'soggetto_nuovo_id' => $nuovoSoggetto->id,
            'data_subentro' => $datiSubentro['data_subentro'],
            'tipo_subentro' => $datiSubentro['tipo_subentro'],
            'quota_nuova' => $datiSubentro['quota'] ?? 1.0000,
            'numero_atto' => $datiSubentro['numero_atto'] ?? null,
            'data_atto' => $datiSubentro['data_atto'] ?? null,
            'notaio' => $datiSubentro['notaio'] ?? null,
            'prezzo_vendita' => $datiSubentro['prezzo_vendita'] ?? null,
            'created_by' => auth()->id()
        ]);
    }

    // === SCOPES AVANZATI ===

    /**
     * Scope per unità con millesimi del tipo specificato
     */
    public function scopeConMillesimi($query, string $tipo = 'proprieta')
    {
        return $query->where("millesimi_{$tipo}", '>', 0);
    }

    /**
     * Scope per unità del piano specificato
     */
    public function scopeDelPiano($query, int $piano)
    {
        return $query->where('piano', $piano);
    }

    /**
     * Scope per unità con superficie minima
     */
    public function scopeConSuperficieMinima($query, float $minima)
    {
        return $query->where('superficie_commerciale', '>=', $minima);
    }

    /**
     * Scope per unità che necessitano lavori
     */
    public function scopeConLavoriNecessari($query)
    {
        return $query->where('necessita_lavori', true);
    }
}