<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\{
    Stabile, 
    Gestione, 
    Fornitore, 
    VoceSpesa, 
    TabellaMillesimale,
    MovimentoContabile,
    TransazioneContabile,
    RigaContabile,
    PianoConti,
    ProtocolloRegistrazione
};

/**
 * ========================================
 * CONTROLLER MASCHERA UNICA REGISTRAZIONE
 * Sistema avanzato partita doppia NetGesCon
 * ========================================
 */
class RegistrazioniController extends Controller
{
    /**
     * Mostra la maschera unica di registrazione
     */
    public function create()
    {
        $amministratore_id = Auth::user()->amministratore->id_amministratore ?? null;
        
        // Dati necessari per la maschera
        $stabili = Stabile::where('amministratore_id', $amministratore_id)->attivi()->get();
        $fornitori = Fornitore::where('amministratore_id', $amministratore_id)->get();
        $vociSpesa = VoceSpesa::orderBy('codice')->get();
        $conti = PianoConti::orderBy('codice_conto')->get();
        
        // Template predefiniti per registrazioni comuni
        $template = [
            'fattura_fornitore' => [
                'nome' => 'Fattura Fornitore',
                'tipo_documento' => 'fattura_passiva',
                'conti_automatici' => [
                    'dare' => ['6000' => 'Costi per servizi'],
                    'avere' => ['2000' => 'Debiti verso fornitori']
                ]
            ],
            'bolletta_utenza' => [
                'nome' => 'Bolletta Utenza',
                'tipo_documento' => 'bolletta',
                'conti_automatici' => [
                    'dare' => ['6100' => 'Spese per utenze'],
                    'avere' => ['2000' => 'Debiti verso fornitori']
                ]
            ],
            'pagamento_bonifico' => [
                'nome' => 'Pagamento Bonifico',
                'tipo_documento' => 'bonifico',
                'conti_automatici' => [
                    'dare' => ['2000' => 'Debiti verso fornitori'],
                    'avere' => ['1000' => 'Banca c/c']
                ]
            ],
            'incasso_rata' => [
                'nome' => 'Incasso Rata Condominiale',
                'tipo_documento' => 'incasso',
                'conti_automatici' => [
                    'dare' => ['1000' => 'Banca c/c'],
                    'avere' => ['3000' => 'Crediti verso condomini']
                ]
            ],
            'ripartizione_spesa' => [
                'nome' => 'Ripartizione Spesa',
                'tipo_documento' => 'ripartizione',
                'conti_automatici' => [
                    'dare' => ['3000' => 'Crediti verso condomini'],
                    'avere' => ['6000' => 'Costi per servizi']
                ]
            ]
        ];

        return view('admin.registrazioni.create', compact(
            'stabili', 'fornitori', 'vociSpesa', 'conti', 'template'
        ));
    }

    /**
     * Salva la registrazione con logica partita doppia
     */
    public function store(Request $request)
    {
        $request->validate([
            'stabile_id' => 'required|exists:stabili,id_stabile',
            'gestione_id' => 'required|exists:gestioni,id_gestione',
            'tipo_documento' => 'required|string',
            'numero_documento' => 'required|string',
            'data_documento' => 'required|date',
            'data_registrazione' => 'required|date',
            'fornitore_id' => 'nullable|exists:fornitori,id_fornitore',
            'descrizione' => 'required|string',
            'note' => 'nullable|string',
            'importo_totale' => 'required|numeric|min:0.01',
            'importo_iva' => 'nullable|numeric|min:0',
            'ritenuta_acconto' => 'nullable|numeric|min:0',
            'righe_contabili' => 'required|array|min:2',
            'righe_contabili.*.conto_id' => 'required|exists:piano_conti,id',
            'righe_contabili.*.tipo_riga' => 'required|in:dare,avere',
            'righe_contabili.*.importo' => 'required|numeric|min:0.01',
            'righe_contabili.*.descrizione' => 'nullable|string',
            'ripartizioni' => 'nullable|array',
            'ripartizioni.*.tabella_millesimale_id' => 'required_with:ripartizioni|exists:tabelle_millesimali,id',
            'ripartizioni.*.voce_spesa_id' => 'required_with:ripartizioni|exists:voci_spesa,id'
        ]);

        DB::beginTransaction();
        try {
            // Verifica quadratura dare/avere
            $totaleDare = collect($request->righe_contabili)
                ->where('tipo_riga', 'dare')
                ->sum('importo');
            
            $totaleAvere = collect($request->righe_contabili)
                ->where('tipo_riga', 'avere')
                ->sum('importo');

            if (abs($totaleDare - $totaleAvere) > 0.01) {
                throw new \Exception('La registrazione non è quadrata. Dare: €' . number_format($totaleDare, 2) . ' - Avere: €' . number_format($totaleAvere, 2));
            }

            // Genera protocolli
            $protocolloGenerale = $this->generaProtocolloGenerale($request->stabile_id);
            $protocolloGestione = $this->generaProtocolloGestione($request->stabile_id, $request->gestione_id);

            // Crea transazione principale
            $transazione = TransazioneContabile::create([
                'stabile_id' => $request->stabile_id,
                'gestione_id' => $request->gestione_id,
                'fornitore_id' => $request->fornitore_id,
                'protocollo_generale' => $protocolloGenerale,
                'protocollo_gestione' => $protocolloGestione,
                'tipo_documento' => $request->tipo_documento,
                'numero_documento' => $request->numero_documento,
                'data_documento' => $request->data_documento,
                'data_registrazione' => $request->data_registrazione,
                'descrizione' => $request->descrizione,
                'note' => $request->note,
                'importo_totale' => $request->importo_totale,
                'importo_iva' => $request->importo_iva ?? 0,
                'ritenuta_acconto' => $request->ritenuta_acconto ?? 0,
                'stato' => 'confermata',
                'quadrata' => true,
                'utente_id' => Auth::id()
            ]);

            // Crea righe contabili
            foreach ($request->righe_contabili as $riga) {
                RigaContabile::create([
                    'transazione_id' => $transazione->id,
                    'conto_id' => $riga['conto_id'],
                    'tipo_riga' => $riga['tipo_riga'],
                    'importo' => $riga['importo'],
                    'descrizione' => $riga['descrizione'] ?? null
                ]);
            }

            // Gestione ripartizioni automatiche se presenti
            if ($request->has('ripartizioni') && count($request->ripartizioni) > 0) {
                $this->processaRipartizioni($transazione, $request->ripartizioni);
            }

            // Aggiorna saldi real-time tramite trigger SQL
            DB::statement('CALL sp_aggiorna_saldi_transazione(?)', [$transazione->id]);

            // Registra nel protocollo
            ProtocolloRegistrazione::create([
                'stabile_id' => $request->stabile_id,
                'gestione_id' => $request->gestione_id,
                'transazione_id' => $transazione->id,
                'protocollo_generale' => $protocolloGenerale,
                'protocollo_gestione' => $protocolloGestione,
                'data_registrazione' => $request->data_registrazione,
                'tipo_protocollo' => 'contabile',
                'utente_id' => Auth::id()
            ]);

            DB::commit();

            return redirect()
                ->route('admin.registrazioni.show', $transazione)
                ->with('success', 'Registrazione contabile salvata con successo. Protocollo: ' . $protocolloGenerale);

        } catch (\Exception $e) {
            DB::rollback();
            return back()
                ->withInput()
                ->withErrors(['error' => 'Errore durante il salvataggio: ' . $e->getMessage()]);
        }
    }

    /**
     * Mostra una registrazione
     */
    public function show(TransazioneContabile $transazione)
    {
        $transazione->load([
            'stabile',
            'gestione', 
            'fornitore',
            'righe.conto',
            'ripartizioni.tabellaMillesimale',
            'ripartizioni.voceSpesa',
            'documentiAllegati'
        ]);

        return view('admin.registrazioni.show', compact('transazione'));
    }

    /**
     * API: Ottieni template per tipo documento
     */
    public function getTemplate($tipoDocumento)
    {
        $templates = [
            'fattura_passiva' => [
                'righe_suggerite' => [
                    ['conto' => '6000', 'tipo' => 'dare', 'descrizione' => 'Costo per servizi'],
                    ['conto' => '1250', 'tipo' => 'dare', 'descrizione' => 'IVA a credito'],
                    ['conto' => '2000', 'tipo' => 'avere', 'descrizione' => 'Debito verso fornitore']
                ]
            ],
            'bonifico' => [
                'righe_suggerite' => [
                    ['conto' => '2000', 'tipo' => 'dare', 'descrizione' => 'Estinzione debito'],
                    ['conto' => '1000', 'tipo' => 'avere', 'descrizione' => 'Uscita da banca']
                ]
            ],
            'incasso' => [
                'righe_suggerite' => [
                    ['conto' => '1000', 'tipo' => 'dare', 'descrizione' => 'Entrata in banca'],
                    ['conto' => '3000', 'tipo' => 'avere', 'descrizione' => 'Estinzione credito']
                ]
            ]
        ];

        return response()->json($templates[$tipoDocumento] ?? []);
    }

    /**
     * API: Calcola ripartizione automatica
     */
    public function calcolaRipartizione(Request $request)
    {
        $request->validate([
            'importo' => 'required|numeric|min:0',
            'tabella_millesimale_id' => 'required|exists:tabelle_millesimali,id',
            'voce_spesa_id' => 'required|exists:voci_spesa,id'
        ]);

        $tabella = TabellaMillesimale::with('quote')->find($request->tabella_millesimale_id);
        $importo = $request->importo;
        
        $ripartizioni = [];
        $totaleQuote = $tabella->quote->sum('quota_millesimi');
        
        foreach ($tabella->quote as $quota) {
            $importoQuota = round(($importo * $quota->quota_millesimi) / $totaleQuote, 2);
            
            $ripartizioni[] = [
                'condomino_id' => $quota->condomino_id,
                'quota_millesimi' => $quota->quota_millesimi,
                'importo' => $importoQuota,
                'condomino' => $quota->condomino->ragione_sociale ?? 'N/A'
            ];
        }

        return response()->json([
            'ripartizioni' => $ripartizioni,
            'totale_ripartito' => array_sum(array_column($ripartizioni, 'importo')),
            'tabella_nome' => $tabella->nome
        ]);
    }

    /**
     * Genera protocollo generale annuale
     */
    private function generaProtocolloGenerale($stabileId)
    {
        $anno = now()->year;
        
        $ultimoProtocollo = ProtocolloRegistrazione::where('stabile_id', $stabileId)
            ->where('tipo_protocollo', 'contabile')
            ->whereYear('data_registrazione', $anno)
            ->max('protocollo_generale');

        $numeroProtocollo = $ultimoProtocollo ? (intval(substr($ultimoProtocollo, -4)) + 1) : 1;
        
        return sprintf('%d-%04d', $anno, $numeroProtocollo);
    }

    /**
     * Genera protocollo per gestione
     */
    private function generaProtocolloGestione($stabileId, $gestioneId)
    {
        $anno = now()->year;
        $gestione = Gestione::find($gestioneId);
        
        $ultimoProtocollo = ProtocolloRegistrazione::where('stabile_id', $stabileId)
            ->where('gestione_id', $gestioneId)
            ->where('tipo_protocollo', 'contabile')
            ->whereYear('data_registrazione', $anno)
            ->max('protocollo_gestione');

        $numeroProtocollo = $ultimoProtocollo ? (intval(substr($ultimoProtocollo, -4)) + 1) : 1;
        
        return sprintf('%s-%d-%04d', strtoupper($gestione->tipo_gestione), $anno, $numeroProtocollo);
    }

    /**
     * Processa ripartizioni automatiche
     */
    private function processaRipartizioni($transazione, $ripartizioni)
    {
        foreach ($ripartizioni as $ripartizione) {
            // Logica per creare ripartizioni automatiche
            // Implementazione dettagliata delle ripartizioni condominiali
        }
    }
}
