<?php

namespace Tests\Feature;

use App\Models\FortuneLog;
use App\Models\GameConfig;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class FortuneTellingControllerTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();

        GameConfig::updateOrCreate(
            ['game_key' => 'fortune_telling'],
            [
                'name' => 'Fortune Telling',
                'icon' => 'fortune',
                'description' => 'Fortune Telling Game',
                'enabled' => true,
                'params' => [
                    'free_count_per_day' => 1,
                    'extra_cost' => 500,
                ],
            ]
        );
    }

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

        $response = $this->actingAs($user)->getJson(route('fortune.today'));

        $response->assertStatus(200);
        $response->assertJson([
            'enabled' => true,
            'today_count' => 0,
            'free_count' => 1,
            'free_used' => 0,
            'has_free_left' => true,
            'extra_cost' => 500,
        ]);
        $response->assertJsonStructure(['latest']);
    }

    public function test_can_tell_free()
    {
        /** @var \App\Models\User $user */
        $user = User::factory()->create(['jjb' => 0]); // Note: 0 jjb needed for free

        $response = $this->actingAs($user)->postJson(route('fortune.tell'));

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

        $this->assertDatabaseHas('fortune_logs', [
            'user_id' => $user->id,
            'is_free' => 1,
        ]);
    }

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

        // Consume free tell
        FortuneLog::create([
            'user_id' => $user->id,
            'grade' => 'great_luck',
            'text' => 'Test',
            'buff_desc' => 'Test',
            'is_free' => true,
            'cost' => 0,
            'fortune_date' => today(),
        ]);

        $response = $this->actingAs($user)->postJson(route('fortune.tell'));

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

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

        // Consume free tell
        FortuneLog::create([
            'user_id' => $user->id,
            'grade' => 'great_luck',
            'text' => 'Test',
            'buff_desc' => 'Test',
            'is_free' => true,
            'cost' => 0,
            'fortune_date' => today(),
        ]);

        $response = $this->actingAs($user)->postJson(route('fortune.tell'));

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

        $this->assertDatabaseHas('fortune_logs', [
            'user_id' => $user->id,
            'is_free' => 0,
            'cost' => 500,
        ]);

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

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

        FortuneLog::create([
            'user_id' => $user->id,
            'grade' => 'great_luck',
            'text' => 'Test',
            'buff_desc' => 'Test',
            'is_free' => true,
            'cost' => 0,
            'fortune_date' => today(),
        ]);

        $response = $this->actingAs($user)->getJson(route('fortune.history'));

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