<?php

namespace Database\Seeders;

use App\Models\OddsItem;
use App\Models\PlayType;
use App\Models\OddsVersion;
use App\Models\RiskCapItem;
use App\Models\PlayConfigItem;
use App\Models\RiskCapVersion;
use Illuminate\Database\Seeder;
use App\Models\PlayConfigVersion;
use Illuminate\Support\Facades\DB;
use App\Support\OddsStandardScopes;
use App\Lottery\ConfigVersionStatus;

/**
 * 阶段 4：写入首套 **active** 玩法配置 / 赔率 / 风控封顶版本（依赖 {@see PlayTypeSeeder}、{@see CurrencySeeder}）。
 *
 * 幂等：仅当三套版本均已有 active 行时跳过；否则只补缺失的一类（避免「仅有 play active 时整段被跳过」导致 /play/effective 不可用）。
 */
final class OperationalConfigV1Seeder extends Seeder
{
    public function run(): void
    {
        $hasPlay = PlayConfigVersion::query()
            ->where('status', ConfigVersionStatus::Active->value)
            ->exists();
        $hasOdds = OddsVersion::query()
            ->where('status', ConfigVersionStatus::Active->value)
            ->exists();
        $hasRisk = RiskCapVersion::query()
            ->where('status', ConfigVersionStatus::Active->value)
            ->exists();

        if ($hasPlay && $hasOdds && $hasRisk) {
            return;
        }

        DB::transaction(function () use ($hasPlay, $hasOdds, $hasRisk): void {
            if (! $hasPlay) {
                $this->seedActivePlayConfigVersion();
            }
            if (! $hasOdds) {
                $this->seedActiveOddsVersion();
            }
            if (! $hasRisk) {
                $this->seedActiveRiskCapVersion();
            }
        });
    }

    private function seedActivePlayConfigVersion(): void
    {
        $versionNo = (int) (PlayConfigVersion::query()->max('version_no') ?? 0) + 1;

        $playVersion = PlayConfigVersion::query()->create([
            'version_no' => $versionNo,
            'status' => ConfigVersionStatus::Active->value,
            'effective_at' => now(),
            'updated_by' => null,
            'reason' => 'seed:v1',
        ]);

        foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $pt) {
            PlayConfigItem::query()->create([
                'version_id' => $playVersion->id,
                'play_code' => $pt->play_code,
                'category' => $pt->category,
                'dimension' => $pt->dimension,
                'bet_mode' => $pt->bet_mode,
                'display_name' => $pt->display_name,
                'is_enabled' => (bool) $pt->is_enabled,
                'min_bet_amount' => 100,
                'max_bet_amount' => 500_000_000,
                'display_order' => (int) $pt->sort_order,
                'supports_multi_number' => (bool) $pt->supports_multi_number,
                'reserved_rule_json' => $pt->reserved_rule_json,
                'rule_text_zh' => null,
                'rule_text_en' => null,
                'rule_text_ne' => null,
                'extra_config_json' => null,
            ]);
        }
    }

    private function seedActiveOddsVersion(): void
    {
        $versionNo = (int) (OddsVersion::query()->max('version_no') ?? 0) + 1;

        $oddsVersion = OddsVersion::query()->create([
            'version_no' => $versionNo,
            'status' => ConfigVersionStatus::Active->value,
            'effective_at' => now(),
            'updated_by' => null,
            'reason' => 'seed:v1',
        ]);

        /** 对齐界面文档 §5.5：头/二/三/特别/安慰；odds_value = 乘数×10000（NPR 基准展示口径） */
        foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $pt) {
            foreach (OddsStandardScopes::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
                OddsItem::query()->create([
                    'version_id' => $oddsVersion->id,
                    'play_code' => $pt->play_code,
                    'prize_scope' => $scope,
                    'dimension' => $pt->dimension,
                    'odds_value' => $oddsValue,
                    'rebate_rate' => 0,
                    'commission_rate' => 0,
                    'currency_code' => 'NPR',
                    'extra_config_json' => null,
                ]);
            }
        }
    }

    private function seedActiveRiskCapVersion(): void
    {
        $versionNo = (int) (RiskCapVersion::query()->max('version_no') ?? 0) + 1;

        $riskVersion = RiskCapVersion::query()->create([
            'version_no' => $versionNo,
            'status' => ConfigVersionStatus::Active->value,
            'effective_at' => now(),
            'updated_by' => null,
            'reason' => 'seed:v1',
        ]);

        RiskCapItem::query()->create([
            'version_id' => $riskVersion->id,
            'draw_id' => null,
            'normalized_number' => '0000',
            'cap_amount' => 50_000_000_000,
            'cap_type' => 'default',
        ]);
    }
}
