<?php

namespace App\Models;

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

class AnagraficaCondominiale extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'anagrafica_condominiale';

    protected $fillable = [
        'amministratore_id',
        'codice_univoco',
        'tipo_soggetto',
        'cognome',
        'nome',
        'denominazione',
        'codice_fiscale',
        'partita_iva',
        'data_nascita',
        'luogo_nascita',
        'provincia_nascita',
        'sesso',
        'indirizzo_residenza',
        'cap_residenza',
        'citta_residenza',
        'provincia_residenza',
        'nazione_residenza',
        'domicilio_diverso',
        'indirizzo_domicilio',
        'cap_domicilio',
        'citta_domicilio',
        'provincia_domicilio',
        'nazione_domicilio',
        'stato',
        'note',
        'google_contact_id',
        'ultima_sincronizzazione_google'
    ];

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

    /**
     * Genera un codice univoco di 8 caratteri con prefisso ANA
     */
    private static function generateUniqueCode()
    {
        do {
            $code = 'ANA' . strtoupper(substr(str_shuffle('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 5));
        } while (self::where('codice_univoco', $code)->exists());
        
        return $code;
    }

    protected $casts = [
        'data_nascita' => 'date',
        'ultima_sincronizzazione_google' => 'datetime',
        'domicilio_diverso' => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime'
    ];

    /**
     * Relazione con i contatti
     */
    public function contatti()
    {
        return $this->hasMany(ContattoAnagrafica::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 DettaglioRipartizioneSpese
     */
    public function dettagliRipartizioneSpese()
    {
        return $this->hasMany(DettaglioRipartizioneSpese::class);
    }

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

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

    /**
     * Scope per tipo soggetto
     */
    public function scopeByTipo($query, $tipo)
    {
        return $query->where('tipo_soggetto', $tipo);
    }

    /**
     * Scope per persone fisiche
     */
    public function scopePersoneFisiche($query)
    {
        return $query->where('tipo_soggetto', 'persona_fisica');
    }

    /**
     * Scope per persone giuridiche
     */
    public function scopePersoneGiuridiche($query)
    {
        return $query->where('tipo_soggetto', 'persona_giuridica');
    }

    /**
     * Accessor per il nome completo
     */
    public function getNomeCompletoAttribute()
    {
        if ($this->tipo_soggetto === 'persona_giuridica') {
            return $this->denominazione;
        }
        
        return trim($this->nome . ' ' . $this->cognome);
    }

    /**
     * Accessor per codice anagrafica (compatibilità)
     */
    public function getCodiceAnagraficaAttribute()
    {
        return $this->codice_univoco;
    }

    /**
     * Accessor per l'indirizzo completo di residenza
     */
    public function getIndirizzoResidenzaCompletoAttribute()
    {
        $indirizzo = $this->indirizzo_residenza;
        if ($this->cap_residenza) {
            $indirizzo .= ', ' . $this->cap_residenza;
        }
        if ($this->citta_residenza) {
            $indirizzo .= ' ' . $this->citta_residenza;
        }
        if ($this->provincia_residenza) {
            $indirizzo .= ' (' . $this->provincia_residenza . ')';
        }
        return $indirizzo;
    }

    /**
     * Accessor per l'indirizzo completo di domicilio
     */
    public function getIndirizzoDomicilioCompletoAttribute()
    {
        if (!$this->domicilio_diverso) {
            return $this->indirizzo_residenza_completo;
        }
        
        $indirizzo = $this->indirizzo_domicilio;
        if ($this->cap_domicilio) {
            $indirizzo .= ', ' . $this->cap_domicilio;
        }
        if ($this->citta_domicilio) {
            $indirizzo .= ' ' . $this->citta_domicilio;
        }
        if ($this->provincia_domicilio) {
            $indirizzo .= ' (' . $this->provincia_domicilio . ')';
        }
        return $indirizzo;
    }

    /**
     * Metodo per ottenere tutti i contatti per tipo (placeholder - table doesn't exist yet)
     */
    public function getContattiByTipo($tipo)
    {
        // TODO: Implementare quando sarà creata la tabella contatti
        return collect();
    }

    /**
     * Metodo per verificare se è attivo
     */
    public function isAttivo()
    {
        return $this->stato === 'attivo';
    }

    /**
     * Metodo per ottenere le unità immobiliari di proprietà
     */
    public function getUnitaImmobiliariProprietario()
    {
        return UnitaImmobiliare::whereHas('dirittiReali', function ($query) {
            $query->where('anagrafica_condominiale_id', $this->id)
                  ->where('tipo_diritto', 'proprieta')
                  ->whereNull('data_fine');
        })->get();
    }

    /**
     * Metodo per ottenere le unità immobiliari in locazione
     */
    public function getUnitaImmobiliariInquilino()
    {
        return UnitaImmobiliare::whereHas('contrattiLocazione', function ($query) {
            $query->where('anagrafica_condominiale_id', $this->id)
                  ->where('stato', 'attivo')
                  ->whereDate('data_inizio', '<=', now())
                  ->where(function ($q) {
                      $q->whereNull('data_fine')
                        ->orWhereDate('data_fine', '>=', now());
                  });
        })->get();
    }

    /**
     * Metodo per verificare se è un proprietario
     */
    public function isProprietario()
    {
        return $this->dirittiReali()
            ->where('tipo_diritto', 'proprieta')
            ->whereNull('data_fine')
            ->exists();
    }

    /**
     * Metodo per verificare se è un inquilino
     */
    public function isInquilino()
    {
        return $this->contrattiLocazione()
            ->where('stato', 'attivo')
            ->whereDate('data_inizio', '<=', now())
            ->where(function ($query) {
                $query->whereNull('data_fine')
                      ->orWhereDate('data_fine', '>=', now());
            })
            ->exists();
    }

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

    /**
     * Metodo per ottenere il bilancio delle spese per questa anagrafica
     */
    public function getBilancioSpese($annoGestione = null)
    {
        $anno = $annoGestione ?? date('Y');
        
        $dettagliRipartizione = $this->dettagliRipartizioneSpese()
            ->whereHas('ripartizioneSpese', function($q) use ($anno) {
                $q->whereYear('data_ripartizione', $anno)
                  ->where('stato', 'confermata');
            })
            ->with('ripartizioneSpese.voceSpesa')
            ->get();

        return [
            'totale_spese' => $dettagliRipartizione->sum('quota_finale'),
            'totale_proprietario' => $dettagliRipartizione->sum('importo_proprietario'),
            'totale_inquilino' => $dettagliRipartizione->sum('importo_inquilino'),
            'numero_voci' => $dettagliRipartizione->count(),
            'dettagli' => $dettagliRipartizione
        ];
    }

    /**
     * Metodo per ottenere le rate in scadenza
     */
    public function getRateInScadenza($giorni = 30)
    {
        return $this->rate()
            ->inScadenza($giorni)
            ->with(['pianoRateizzazione', 'unitaImmobiliare'])
            ->get();
    }
}
