<?php

namespace E2E\Seeders;

use App\Models\AdminSite;
use App\Models\AdminUser;
use App\Models\Player;
use App\Models\PlayerWallet;
use App\Services\Agent\AgentNodeService;
use App\Support\PlayerAuthSource;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

/**
 * E2E 专用：建可登录玩家 + demo 接入站（含根代理、SSO 密钥、mock 钱包 URL）。
 *
 * 命名空间 E2E\Seeders（不在 Database\Seeders\ 下，避免与生产 seeder 撞类名）。
 * 由 e2e/scripts/run.sh 在 migrate:fresh --seed 后显式调用。
 */
final class E2EPlayerSeeder extends Seeder
{
    public function run(): void
    {
        $siteCode = (string) env('E2E_PLAYER_SITE_CODE', 'demo');
        $username = (string) env('E2E_PLAYER_USERNAME', 'demo_player');
        $password = (string) env('E2E_PLAYER_PASSWORD', '12345678');
        $currency = strtoupper((string) env('LOTTERY_DEFAULT_CURRENCY', config('lottery.default_currency', 'NPR')));
        $balance = (int) env('DEV_SEED_WALLET_BALANCE_MINOR', 1_250_000);
        $mockWalletPort = (string) env('E2E_MOCK_WALLET_PORT', '5555');

        $this->ensureDemoIntegrationSite($siteCode, $currency, $mockWalletPort);
        $this->ensureE2ELeafAgent($siteCode, $password);

        // LocalDemoSeeder 可能已建无 password_hash 的 demo_player；合并为一条可登录行。
        Player::query()
            ->where('site_code', $siteCode)
            ->where('username', $username)
            ->where('site_player_id', '!=', 'e2e-001')
            ->delete();

        /** @var Player $player */
        $player = Player::query()->updateOrCreate(
            ['site_code' => $siteCode, 'username' => $username],
            [
                'site_player_id' => 'e2e-001',
                'password_hash' => Hash::make($password),
                'auth_source' => PlayerAuthSource::LOTTERY_NATIVE,
                'funding_mode' => 'wallet',
                'nickname' => 'E2E Player',
                'default_currency' => $currency,
                'status' => 0,
                'login_failed_count' => 0,
            ],
        );

        PlayerWallet::query()->updateOrCreate(
            ['player_id' => $player->id, 'wallet_type' => 'lottery', 'currency_code' => $currency],
            [
                'balance' => $balance,
                'frozen_balance' => 0,
                'status' => 0,
                'version' => 0,
            ],
        );
    }

    private function ensureDemoIntegrationSite(string $siteCode, string $currency, string $mockWalletPort): void
    {
        $walletBase = 'http://127.0.0.1:'.trim($mockWalletPort);

        AdminSite::query()->updateOrCreate(
            ['code' => $siteCode],
            [
                'name' => 'E2E Demo Site',
                'currency_code' => $currency,
                'status' => 1,
                'is_default' => false,
                'extra_json' => ['source' => 'e2e'],
                'wallet_api_url' => $walletBase,
                'wallet_debit_path' => '/wallet/debit-for-lottery',
                'wallet_credit_path' => '/wallet/credit-from-lottery',
                'wallet_balance_path' => '/wallet/balance',
                'wallet_api_key_encrypted' => encrypt('e2e-mock-key'),
                'sso_jwt_secret_encrypted' => encrypt('e2e-sso-secret'),
                'wallet_timeout_seconds' => 10,
            ],
        );

        $siteId = (int) AdminSite::query()->where('code', $siteCode)->value('id');
        if ($siteId <= 0) {
            return;
        }

        $rootId = (int) DB::table('agent_nodes')
            ->where('admin_site_id', $siteId)
            ->where('depth', 0)
            ->value('id');

        if ($rootId <= 0) {
            $now = now();
            $rootId = (int) DB::table('agent_nodes')->insertGetId([
                'admin_site_id' => $siteId,
                'parent_id' => null,
                'path' => '/',
                'depth' => 0,
                'code' => 'root-'.$siteCode,
                'name' => 'E2E Root',
                'status' => 1,
                'created_by' => null,
                'extra_json' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
            DB::table('agent_nodes')->where('id', $rootId)->update([
                'path' => '/'.$rootId.'/',
            ]);
        }

        if (! DB::table('agent_profiles')->where('agent_node_id', $rootId)->exists()) {
            $defaults = config('agent_line_defaults', []);
            $now = now();
            DB::table('agent_profiles')->insert([
                'agent_node_id' => $rootId,
                'total_share_rate' => (float) ($defaults['total_share_rate'] ?? 100),
                'credit_limit' => (int) ($defaults['credit_limit'] ?? 0) > 0
                    ? (int) $defaults['credit_limit']
                    : 1_000_000,
                'allocated_credit' => 0,
                'used_credit' => 0,
                'rebate_limit' => (float) ($defaults['rebate_limit'] ?? 0.005),
                'default_player_rebate' => (float) ($defaults['default_player_rebate'] ?? 0.005),
                'can_grant_extra_rebate' => true,
                'can_create_child_agent' => true,
                'can_create_player' => true,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }
    }

    private function ensureE2ELeafAgent(string $siteCode, string $password): void
    {
        $siteId = (int) AdminSite::query()->where('code', $siteCode)->value('id');
        if ($siteId <= 0) {
            return;
        }

        $exists = DB::table('admin_users')->where('username', 'e2e_leaf_agent')->exists();
        if ($exists) {
            return;
        }

        $rootId = (int) DB::table('agent_nodes')
            ->where('admin_site_id', $siteId)
            ->where('depth', 0)
            ->value('id');
        if ($rootId <= 0) {
            return;
        }

        $super = AdminUser::query()->where('username', 'admin')->first();
        if ($super === null) {
            return;
        }

        app(AgentNodeService::class)->createChild($super, [
            'parent_id' => $rootId,
            'code' => 'e2e_leaf',
            'name' => 'E2E Leaf Agent',
            'username' => 'e2e_leaf_agent',
            'password' => $password,
            'total_share_rate' => 25,
            'credit_limit' => 200_000,
            'rebate_limit' => 0.01,
            'default_player_rebate' => 0.005,
        ]);
    }
}
