<?php

namespace App\Helpers;

use App\Models\Stabile;
use App\Models\Soggetto;
use App\Models\Ticket;
use App\Models\Fornitore;
use App\Models\Rata;
use App\Models\UnitaImmobiliare;
use App\Models\Assemblea;
use App\Models\MovimentoContabile;
use App\Models\Documento;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Carbon\Carbon;

class DashboardDataHelper
{
    /**
     * Ottiene dati reali per la dashboard principale
     */
    public static function getDashboardData()
    {
        return Cache::remember('dashboard_data', 300, function () {
            return [
                'stabili' => self::getStabiliData(),
                'condomini' => self::getCondominiData(), 
                'contabilita' => self::getContabilitaData(),
                'tickets' => self::getTicketsData(),
                'assemblee' => self::getAssembleeData(),
                'sistema' => self::getSistemaData(),
            ];
        });
    }

    /**
     * Dati degli stabili con dettagli aggiuntivi
     */
    private static function getStabiliData()
    {
        try {
            $totaleStabili = Stabile::count();
            $stabiliAttivi = Stabile::where('stato', 'attivo')->count();
            $unitaTotali = UnitaImmobiliare::count();
            $unitaOccupate = UnitaImmobiliare::whereHas('proprietari')->count();
            
            return [
                'totale' => $totaleStabili,
                'attivi' => $stabiliAttivi,
                'inattivi' => $totaleStabili - $stabiliAttivi,
                'unita_totali' => $unitaTotali,
                'unita_occupate' => $unitaOccupate,
                'unita_libere' => $unitaTotali - $unitaOccupate,
                'percentuale_occupazione' => $unitaTotali > 0 ? round(($unitaOccupate / $unitaTotali) * 100, 1) : 0,
            ];
        } catch (\Exception $e) {
            return [
                'totale' => 0, 'attivi' => 0, 'inattivi' => 0,
                'unita_totali' => 0, 'unita_occupate' => 0, 'unita_libere' => 0,
                'percentuale_occupazione' => 0
            ];
        }
    }

    /**
     * Dati dei condomini con classificazioni
     */
    private static function getCondominiData()
    {
        try {
            $totaleCondomini = Soggetto::count();
            $proprietari = Soggetto::where('tipo', 'proprietario')->count();
            $inquilini = Soggetto::where('tipo', 'inquilino')->count();
            
            return [
                'totale' => $totaleCondomini,
                'proprietari' => $proprietari,
                'inquilini' => $inquilini,
                'altri' => $totaleCondomini - $proprietari - $inquilini,
                'percentuale_proprietari' => $totaleCondomini > 0 ? round(($proprietari / $totaleCondomini) * 100, 1) : 0,
            ];
        } catch (\Exception $e) {
            return [
                'totale' => 0, 'proprietari' => 0, 'inquilini' => 0, 'altri' => 0,
                'percentuale_proprietari' => 0
            ];
        }
    }

    /**
     * Dati della contabilità con trend
     */
    private static function getContabilitaData()
    {
        try {
            $oggi = Carbon::now();
            $meseScorso = $oggi->copy()->subMonth();
            
            $rateScadute = Rata::where('data_scadenza', '<', $oggi)
                ->where('stato', '!=', 'pagata')
                ->count();
                
            $incassiMeseCorrente = Rata::whereMonth('data_pagamento', $oggi->month)
                ->whereYear('data_pagamento', $oggi->year)
                ->where('stato', 'pagata')
                ->sum('importo');
                
            $incassiMeseScorso = Rata::whereMonth('data_pagamento', $meseScorso->month)
                ->whereYear('data_pagamento', $meseScorso->year)
                ->where('stato', 'pagata')
                ->sum('importo');
            
            return [
                'rate_scadute' => $rateScadute,
                'rate_del_mese' => Rata::whereMonth('data_scadenza', $oggi->month)
                    ->whereYear('data_scadenza', $oggi->year)
                    ->count(),
                'incassi_mese_corrente' => $incassiMeseCorrente,
                'incassi_mese_scorso' => $incassiMeseScorso,
                'trend_incassi' => $incassiMeseScorso > 0 ? 
                    round((($incassiMeseCorrente - $incassiMeseScorso) / $incassiMeseScorso) * 100, 1) : 0,
                'movimenti_mese' => MovimentoContabile::whereMonth('data_movimento', $oggi->month)
                    ->whereYear('data_movimento', $oggi->year)
                    ->count(),
            ];
        } catch (\Exception $e) {
            return [
                'rate_scadute' => 0, 'rate_del_mese' => 0,
                'incassi_mese_corrente' => 0, 'incassi_mese_scorso' => 0,
                'trend_incassi' => 0, 'movimenti_mese' => 0
            ];
        }
    }

    /**
     * Dati dei tickets con priorità e tempi
     */
    private static function getTicketsData()
    {
        try {
            $ticketsAperti = Ticket::where('stato', 'aperto')->count();
            $ticketsUrgenti = Ticket::where('priorita', 'alta')
                ->where('stato', '!=', 'chiuso')
                ->count();
            $ticketsInLavorazione = Ticket::where('stato', 'in_lavorazione')->count();
            $ticketsChiusiOggi = Ticket::where('stato', 'chiuso')
                ->whereDate('updated_at', Carbon::today())
                ->count();
                
            return [
                'aperti' => $ticketsAperti,
                'urgenti' => $ticketsUrgenti,
                'in_lavorazione' => $ticketsInLavorazione,
                'chiusi_oggi' => $ticketsChiusiOggi,
                'totali' => Ticket::count(),
                'percentuale_risoluzione' => $ticketsAperti + $ticketsInLavorazione > 0 ? 
                    round(($ticketsChiusiOggi / ($ticketsAperti + $ticketsInLavorazione + $ticketsChiusiOggi)) * 100, 1) : 100,
            ];
        } catch (\Exception $e) {
            return [
                'aperti' => 0, 'urgenti' => 0, 'in_lavorazione' => 0,
                'chiusi_oggi' => 0, 'totali' => 0, 'percentuale_risoluzione' => 100
            ];
        }
    }

    /**
     * Dati delle assemblee con calendario
     */
    private static function getAssembleeData()
    {
        try {
            $oggi = Carbon::now();
            $prossimi30Giorni = $oggi->copy()->addDays(30);
            
            return [
                'prossime' => Assemblea::where('data_assemblea', '>', $oggi)->count(),
                'prossimi_30_giorni' => Assemblea::whereBetween('data_assemblea', [$oggi, $prossimi30Giorni])->count(),
                'questo_mese' => Assemblea::whereMonth('data_assemblea', $oggi->month)
                    ->whereYear('data_assemblea', $oggi->year)
                    ->count(),
                'delibere_da_approvare' => Assemblea::where('stato', 'bozza')->count(),
                'verbali_da_completare' => Assemblea::where('stato', 'verbale_incompleto')->count(),
            ];
        } catch (\Exception $e) {
            return [
                'prossime' => 0, 'prossimi_30_giorni' => 0, 'questo_mese' => 0,
                'delibere_da_approvare' => 0, 'verbali_da_completare' => 0
            ];
        }
    }

    /**
     * Dati generali del sistema
     */
    private static function getSistemaData()
    {
        try {
            return [
                'utenti_attivi' => DB::table('users')->where('active', true)->count(),
                'ultimo_backup' => self::getLastBackupDate(),
                'spazio_documenti' => self::getDocumentsSpaceUsage(),
                'uptime' => self::getSystemUptime(),
                'versione' => config('app.version', '2.1.0'),
            ];
        } catch (\Exception $e) {
            return [
                'utenti_attivi' => 1,
                'ultimo_backup' => 'Non disponibile',
                'spazio_documenti' => 'Non disponibile',
                'uptime' => 'Non disponibile',
                'versione' => '2.1.0'
            ];
        }
    }

    /**
     * Ottiene la data dell'ultimo backup
     */
    private static function getLastBackupDate()
    {
        // Implementazione placeholder - sostituire con logica reale
        return Carbon::now()->subDays(1)->format('d/m/Y H:i');
    }

    /**
     * Ottiene l'utilizzo dello spazio per i documenti
     */
    private static function getDocumentsSpaceUsage()
    {
        // Implementazione placeholder - sostituire con logica reale
        return '245 MB utilizzati';
    }

    /**
     * Ottiene l'uptime del sistema
     */
    private static function getSystemUptime()
    {
        // Implementazione placeholder - sostituire con logica reale
        return '15 giorni, 8 ore';
    }

    /**
     * Pulisce la cache
     */
    public static function clearCache()
    {
        Cache::forget('dashboard_data');
    }
}
