<?php

namespace Tests\Unit;

use App\Services\RipartizioneSpesaService;
use App\Models\RipartizioneSpese;
use App\Models\VoceSpesa;
use App\Models\Stabile;
use App\Models\User;
use App\Models\TabellaMillesimale;
use App\Models\UnitaImmobiliare;
use App\Models\AnagraficaCondominiale;
use App\Models\DirittoReale;
use App\Models\PianoRateizzazione;
use App\Models\Rata;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RipartizioneSpesaServiceTest extends TestCase
{
    use RefreshDatabase;

    protected RipartizioneSpesaService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = new RipartizioneSpesaService();
    }

    public function test_calcola_ripartizione_automatica()
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $stabile = Stabile::factory()->create();
        $tabellaMillesimale = TabellaMillesimale::factory()->create([
            'stabile_id' => $stabile->id,
            'totale_millesimi' => 1000,
        ]);
        
        $voceSpesa = VoceSpesa::factory()->create([
            'stabile_id' => $stabile->id,
            'tabella_millesimale_default_id' => $tabellaMillesimale->id,
        ]);

        // Crea unità immobiliare con anagrafica
        $anagrafica = AnagraficaCondominiale::factory()->create();
        $unita = UnitaImmobiliare::factory()->create([
            'stabile_id' => $stabile->id,
            'millesimi_proprieta' => 100.000,
        ]);
        
        DirittoReale::create([
            'unita_immobiliare_id' => $unita->id,
            'anagrafica_id' => $anagrafica->id,
            'tipo_diritto' => 'proprieta',
            'percentuale_proprieta' => 100.00,
            'attivo' => true,
        ]);

        $ripartizione = $this->service->calcolaRipartizione($voceSpesa, 1000.00);

        $this->assertInstanceOf(RipartizioneSpese::class, $ripartizione);
        $this->assertEquals(1000.00, $ripartizione->importo_totale);
        $this->assertEquals($tabellaMillesimale->id, $ripartizione->tabella_millesimale_id);
        $this->assertEquals(1, $ripartizione->dettagli()->count());
        
        $dettaglio = $ripartizione->dettagli()->first();
        $this->assertEquals(100.00, $dettaglio->importo_calcolato); // 1000 * 100/1000
        $this->assertEquals(100.000, $dettaglio->millesimi);
    }

    public function test_crea_piano_rateizzazione()
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $stabile = Stabile::factory()->create();
        $ripartizione = RipartizioneSpese::factory()->create([
            'stabile_id' => $stabile->id,
            'importo_totale' => 1000.00,
            'creato_da' => $user->id,
        ]);

        $piano = $this->service->creaPianoRateizzazione($ripartizione, 5, 'mensile');

        $this->assertInstanceOf(PianoRateizzazione::class, $piano);
        $this->assertEquals(5, $piano->numero_rate);
        $this->assertEquals(1000.00, $piano->importo_totale);
        $this->assertEquals('mensile', $piano->frequenza);
        $this->assertEquals(5, $piano->rate()->count());
        
        // Verifica che le rate siano generate correttamente
        $rate = $piano->rate()->orderBy('numero_rata')->get();
        $this->assertEquals(200.00, $rate->first()->importo_rata);
        $this->assertEquals(200.00, $rate->last()->importo_rata);
    }

    public function test_registra_pagamento_rata()
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $rata = Rata::factory()->create([
            'importo_rata' => 200.00,
            'stato' => 'attiva',
        ]);

        $risultato = $this->service->registraPagamento(
            $rata,
            200.00,
            now(),
            'bonifico',
            'TXN123456'
        );

        $this->assertTrue($risultato);
        
        $rata->refresh();
        $this->assertEquals('pagata', $rata->stato);
        $this->assertEquals(200.00, $rata->importo_pagato);
        $this->assertEquals('bonifico', $rata->modalita_pagamento);
        $this->assertEquals('TXN123456', $rata->riferimento_pagamento);
        $this->assertNotNull($rata->data_pagamento);
    }

    public function test_approva_ripartizione()
    {
        $user = User::factory()->create();
        $this->actingAs($user);

        $ripartizione = RipartizioneSpese::factory()->create([
            'stato' => 'bozza',
            'creato_da' => $user->id,
        ]);

        $risultato = $this->service->approvaRipartizione($ripartizione);

        $this->assertTrue($risultato);
        
        $ripartizione->refresh();
        $this->assertEquals('approvata', $ripartizione->stato);
        $this->assertNotNull($ripartizione->approvato_at);
        $this->assertEquals($user->id, $ripartizione->approvato_da);
    }

    public function test_calcola_statistiche()
    {
        $user = User::factory()->create();
        $ripartizione = RipartizioneSpese::factory()->create([
            'importo_totale' => 1000.00,
            'importo_ripartito' => 950.00,
            'creato_da' => $user->id,
        ]);

        // Crea alcuni dettagli
        $ripartizione->dettagli()->createMany([
            [
                'unita_immobiliare_id' => 1,
                'anagrafica_condominiale_id' => 1,
                'millesimi' => 100.000,
                'importo_calcolato' => 300.00,
            ],
            [
                'unita_immobiliare_id' => 2,
                'anagrafica_condominiale_id' => 2,
                'millesimi' => 150.000,
                'importo_calcolato' => 450.00,
            ],
            [
                'unita_immobiliare_id' => 3,
                'anagrafica_condominiale_id' => 3,
                'millesimi' => 80.000,
                'importo_calcolato' => 200.00,
            ],
        ]);

        $statistiche = $this->service->calcolaStatistiche($ripartizione);

        $this->assertEquals(3, $statistiche['numero_unita']);
        $this->assertEquals(1000.00, $statistiche['importo_totale']);
        $this->assertEquals(950.00, $statistiche['importo_ripartito']);
        $this->assertEquals(50.00, $statistiche['differenza']);
        $this->assertEquals(316.67, round($statistiche['importo_medio_unita'], 2));
        $this->assertEquals(200.00, $statistiche['importo_min_unita']);
        $this->assertEquals(450.00, $statistiche['importo_max_unita']);
        $this->assertEquals(330.000, $statistiche['millesimi_totali']);
    }
}
