<?php

/**
 * 文件功能：赛马竞猜局次模型
 *
 * 代表一场赛马比赛，包含参赛马匹信息、场次状态、
 * 注池统计以及赛果信息。提供当前场次查询和赔率计算方法。
 *
 * @author  ChatRoom Laravel
 *
 * @version 1.0.0
 */

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class HorseRace extends Model
{
    protected $fillable = [
        'status',
        'bet_opens_at',
        'bet_closes_at',
        'race_starts_at',
        'race_ends_at',
        'horses',
        'winner_horse_id',
        'total_bets',
        'total_pool',
        'settled_at',
    ];

    /**
     * 属性类型转换。
     */
    protected function casts(): array
    {
        return [
            'bet_opens_at' => 'datetime',
            'bet_closes_at' => 'datetime',
            'race_starts_at' => 'datetime',
            'race_ends_at' => 'datetime',
            'settled_at' => 'datetime',
            'horses' => 'array',
            'winner_horse_id' => 'integer',
            'total_bets' => 'integer',
            'total_pool' => 'integer',
        ];
    }

    /**
     * 本场所有下注记录。
     */
    public function bets(): HasMany
    {
        return $this->hasMany(HorseBet::class, 'race_id');
    }

    /**
     * 判断当前是否在押注时间窗口内。
     */
    public function isBettingOpen(): bool
    {
        return $this->status === 'betting'
            && now()->between($this->bet_opens_at, $this->bet_closes_at);
    }

    /**
     * 查询当前正在进行的场次（状态为 betting 且押注未截止）。
     */
    public static function currentRace(): ?static
    {
        return static::query()
            ->whereIn('status', ['betting', 'running'])
            ->latest()
            ->first();
    }

    /**
     * 生成参赛马匹列表（根据马匹数量随机选名）。
     *
     * @param  int  $count  马匹数量
     * @return array<int, array{id: int, name: string, emoji: string}>
     */
    public static function generateHorses(int $count): array
    {
        // 可用马匹名池（原版竞技风格）
        $namePool = [
            ['name' => '赤兔', 'emoji' => '🐎'],
            ['name' => '乌骓', 'emoji' => '🐴'],
            ['name' => '的卢', 'emoji' => '🎠'],
            ['name' => '绝影', 'emoji' => '🦄'],
            ['name' => '紫骍', 'emoji' => '🐎'],
            ['name' => '爪黄', 'emoji' => '🐴'],
            ['name' => '汗血', 'emoji' => '🎠'],
            ['name' => '飞电', 'emoji' => '⚡'],
        ];

        // 随机打乱并取前 N 个
        shuffle($namePool);
        $selected = array_slice($namePool, 0, $count);

        $horses = [];
        foreach ($selected as $i => $horse) {
            $horses[] = [
                'id' => $i + 1,
                'name' => $horse['name'],
                'emoji' => $horse['emoji'],
            ];
        }

        return $horses;
    }

    /**
     * 根据注池计算各马匹实时赔率（彩池制，扣除庄家抽水后按比例分配）。
     *
     * @param  int  $horseBetAmounts  各马匹的注额数组 [horse_id => amount]
     * @param  int  $housePercent  庄家抽水百分比
     * @return array<int, float> horse_id => 赔率（含本金）
     */
    public static function calcOdds(array $horseBetAmounts, int $housePercent): array
    {
        $totalPool = array_sum($horseBetAmounts);

        if ($totalPool <= 0) {
            // 尚无下注，返回等额赔率
            $count = count($horseBetAmounts);

            return array_map(fn () => 1.0, $horseBetAmounts);
        }

        $netPool = $totalPool * (1 - $housePercent / 100);
        $odds = [];

        foreach ($horseBetAmounts as $horseId => $amount) {
            if ($amount <= 0) {
                // 无人押注的马，赔率设为理论最大值
                $odds[$horseId] = round($netPool, 2);
            } else {
                // 赔率 = 净注池 / 该马注额（含本金返还）
                $odds[$horseId] = round($netPool / $amount, 2);
            }
        }

        return $odds;
    }
}
