<?php

/**
 * 文件功能：AI小班长资金调度服务测试
 *
 * 覆盖 AI小班长的常规存款、大额调款与阶段性目标公告逻辑，
 * 防止后续调整后再次出现“超过 100 万未存款”或银行调款异常。
 */

namespace Tests\Feature;

use App\Events\MessageSent;
use App\Jobs\SaveMessageJob;
use App\Models\User;
use App\Services\AiFinanceService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;

/**
 * 验证 AI小班长的常规存款与大额调仓规则。
 */
class AiFinanceServiceTest extends TestCase
{
    use RefreshDatabase;

    /**
     * 常规支出只检查手上金币，不会为了凑够金额自动从银行取款。
     */
    public function test_prepare_spend_only_checks_wallet_gold_without_withdrawing_from_bank(): void
    {
        $user = User::factory()->create([
            'jjb' => 700000,
            'bank_jjb' => 600000,
        ]);

        $result = app(AiFinanceService::class)->prepareSpend($user, 800000);

        $this->assertFalse($result);
        $this->assertDatabaseHas('users', [
            'id' => $user->id,
            'jjb' => 700000,
            'bank_jjb' => 600000,
        ]);
        $this->assertDatabaseMissing('bank_logs', [
            'user_id' => $user->id,
            'type' => 'withdraw',
        ]);
    }

    /**
     * 大额支出场景允许从银行提取差额，把目标下注额调到手上。
     */
    public function test_prepare_all_in_spend_withdraws_needed_gold_from_bank(): void
    {
        $user = User::factory()->create([
            'jjb' => 1000000,
            'bank_jjb' => 200000,
        ]);

        $result = app(AiFinanceService::class)->prepareAllInSpend($user, 1150000);

        $this->assertTrue($result);
        $this->assertDatabaseHas('users', [
            'id' => $user->id,
            'jjb' => 1150000,
            'bank_jjb' => 50000,
        ]);

        $this->assertDatabaseHas('bank_logs', [
            'user_id' => $user->id,
            'type' => 'withdraw',
            'amount' => 150000,
            'balance_after' => 50000,
        ]);
    }

    /**
     * 超过 100 万的金币会自动存入银行，并在跨过阶段目标时发送全站公告。
     */
    public function test_bank_excess_gold_deposits_surplus_and_broadcasts_when_crossing_milestone(): void
    {
        Event::fake([MessageSent::class]);
        Queue::fake([SaveMessageJob::class]);

        $user = User::factory()->create([
            'username' => 'AI小班长',
            'jjb' => 1250000,
            'bank_jjb' => 9900000,
        ]);

        app(AiFinanceService::class)->bankExcessGold($user);

        $this->assertDatabaseHas('users', [
            'id' => $user->id,
            'jjb' => 1000000,
            'bank_jjb' => 10150000,
        ]);

        $this->assertDatabaseHas('bank_logs', [
            'user_id' => $user->id,
            'type' => 'deposit',
            'amount' => 250000,
            'balance_after' => 10150000,
        ]);

        Event::assertDispatched(MessageSent::class);
        Queue::assertPushed(SaveMessageJob::class);
    }
}
