<?php

namespace Tests\Feature;

use App\Models\Marriage;
use App\Models\User;
use App\Models\WeddingCeremony;
use App\Models\WeddingEnvelopeClaim;
use App\Models\WeddingTier;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;

class WeddingControllerTest extends TestCase
{
    use RefreshDatabase;

    private function createLegacyMarriageData()
    {
        return [
            'hyname' => 'test',
            'hyname1' => 'test1',
            'hytime' => now(),
            'hygb' => 'test',
            'hyjb' => 'test',
            'i' => 0,
        ];
    }

    public function test_can_get_tiers()
    {
        /** @var \App\Models\User $user */
        $user = User::factory()->create();

        WeddingTier::forceCreate([
            'tier' => 1,
            'name' => 'Basic Wedding',
            'icon' => 'basic',
            'amount' => 1000,
            'description' => 'A basic wedding',
            'is_active' => true,
        ]);

        $response = $this->actingAs($user)->getJson(route('wedding.tiers'));

        $response->assertStatus(200);
        $response->assertJsonStructure(['tiers']);
        $this->assertCount(1, $response->json('tiers'));
    }

    public function test_can_setup_wedding()
    {
        Event::fake();

        /** @var \App\Models\User $user */
        $user = User::factory()->create(['jjb' => 10000]);
        /** @var \App\Models\User $partner */
        $partner = User::factory()->create();

        $marriage = Marriage::create(array_merge([
            'user_id' => $user->id,
            'partner_id' => $partner->id,
            'status' => 'married',
            'married_at' => now(),
        ], $this->createLegacyMarriageData()));

        $tier = WeddingTier::forceCreate([
            'tier' => 1,
            'name' => 'Basic Wedding',
            'icon' => 'basic',
            'amount' => 1000,
            'description' => 'A basic wedding',
            'is_active' => true,
        ]);

        $response = $this->actingAs($user)->postJson(route('wedding.setup', ['marriage' => $marriage->id]), [
            'tier_id' => $tier->id,
            'payer_type' => 'groom',
        ]);

        $response->assertStatus(200);
        $response->assertJson(['ok' => true]);

        Event::assertDispatched(\App\Events\WeddingCelebration::class);
    }

    public function test_can_claim_envelope()
    {
        /** @var \App\Models\User $user */
        $user = User::factory()->create(['jjb' => 0]);
        /** @var \App\Models\User $groom */
        $groom = User::factory()->create();
        /** @var \App\Models\User $bride */
        $bride = User::factory()->create();

        $marriage = Marriage::create(array_merge([
            'user_id' => $groom->id,
            'partner_id' => $bride->id,
            'status' => 'married',
            'married_at' => now(),
        ], $this->createLegacyMarriageData()));

        $tier = WeddingTier::forceCreate([
            'tier' => 1,
            'name' => 'Basic Wedding',
            'icon' => 'basic',
            'amount' => 1000,
            'description' => 'A basic wedding',
            'is_active' => true,
        ]);

        $ceremony = WeddingCeremony::forceCreate([
            'marriage_id' => $marriage->id,
            'tier_id' => $tier->id,
            'total_amount' => 1000,
            'payer_type' => 'groom',
            'groom_amount' => 1000,
            'partner_amount' => 0,
            'ceremony_type' => 'immediate',
            'status' => 'active',
            'expires_at' => now()->addHour(),
        ]);

        // Mock existing envelope claim waiting to be claimed
        WeddingEnvelopeClaim::forceCreate([
            'ceremony_id' => $ceremony->id,
            'user_id' => $user->id,
            'amount' => 100,
            'claimed' => false,
        ]);

        $response = $this->actingAs($user)->postJson(route('wedding.claim', ['ceremony' => $ceremony->id]));

        $response->assertStatus(200);
        $response->assertJson(['ok' => true]);

        $this->assertEquals(100, $user->fresh()->jjb);
    }

    public function test_can_get_envelope_status()
    {
        /** @var \App\Models\User $user */
        $user = User::factory()->create();
        /** @var \App\Models\User $groom */
        $groom = User::factory()->create();
        /** @var \App\Models\User $bride */
        $bride = User::factory()->create();

        $marriage = Marriage::create(array_merge([
            'user_id' => $groom->id,
            'partner_id' => $bride->id,
            'status' => 'married',
            'married_at' => now(),
        ], $this->createLegacyMarriageData()));

        $tier = WeddingTier::forceCreate([
            'tier' => 1,
            'name' => 'Basic',
            'icon' => 'basic',
            'amount' => 1000,
            'description' => 'basic',
            'is_active' => true,
        ]);

        $ceremony = WeddingCeremony::forceCreate([
            'marriage_id' => $marriage->id,
            'tier_id' => $tier->id,
            'total_amount' => 1000,
            'payer_type' => 'groom',
            'groom_amount' => 1000,
            'partner_amount' => 0,
            'ceremony_type' => 'immediate',
            'status' => 'active',
            'expires_at' => now()->addHour(),
        ]);

        WeddingEnvelopeClaim::forceCreate([
            'ceremony_id' => $ceremony->id,
            'user_id' => $user->id,
            'amount' => 100,
            'claimed' => false,
        ]);

        $response = $this->actingAs($user)->getJson(route('wedding.envelope-status', ['ceremony' => $ceremony->id]));

        $response->assertStatus(200);
        $response->assertJson([
            'has_envelope' => true,
            'amount' => 100,
        ]);
    }

    public function test_can_get_pending_envelopes()
    {
        /** @var \App\Models\User $user */
        $user = User::factory()->create();
        /** @var \App\Models\User $groom */
        $groom = User::factory()->create();
        /** @var \App\Models\User $bride */
        $bride = User::factory()->create();

        $marriage = Marriage::create(array_merge([
            'user_id' => $groom->id,
            'partner_id' => $bride->id,
            'status' => 'married',
            'married_at' => now(),
        ], $this->createLegacyMarriageData()));

        $tier = WeddingTier::forceCreate([
            'tier' => 1,
            'name' => 'Basic',
            'icon' => 'basic',
            'amount' => 1000,
            'description' => 'basic',
            'is_active' => true,
        ]);

        $ceremony = WeddingCeremony::forceCreate([
            'marriage_id' => $marriage->id,
            'tier_id' => $tier->id,
            'total_amount' => 1000,
            'payer_type' => 'groom',
            'groom_amount' => 1000,
            'partner_amount' => 0,
            'ceremony_type' => 'immediate',
            'status' => 'active',
            'expires_at' => now()->addHour(),
        ]);

        WeddingEnvelopeClaim::forceCreate([
            'ceremony_id' => $ceremony->id,
            'user_id' => $user->id,
            'amount' => 100,
            'claimed' => false,
        ]);

        $response = $this->actingAs($user)->getJson(route('wedding.pending-envelopes'));

        $response->assertStatus(200);
        $response->assertJsonStructure(['envelopes']);
        $this->assertCount(1, $response->json('envelopes'));
        $this->assertEquals($ceremony->id, $response->json('envelopes.0.ceremony_id'));
    }
}
