<?php

/**
 * 文件功能：赛马结算广播事件
 *
 * 跑马结束後广播赛果（获胜马匹、赔付金额等）给房间所有用户，
 * 前端收到后展示结算面板并更新中奖信息。
 *
 * @author  ChatRoom Laravel
 *
 * @version 1.0.0
 */

namespace App\Events;

use App\Models\GameConfig;
use App\Models\HorseBet;
use App\Models\HorseRace;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

/**
 * 类功能：赛马结算广播事件
 *
 * 向房间公共频道广播最终赛果，并附带前端展示个人奖金所需的
 * 奖池分配参数，避免结算弹窗只能显示固定的 0 金币。
 */
class HorseRaceSettled implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * @param  HorseRace  $race  已结算的场次
     */
    public function __construct(
        public readonly HorseRace $race,
    ) {}

    /**
     * 广播至房间公共频道。
     *
     * @return array<\Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [new PresenceChannel('room.1')];
    }

    /**
     * 广播事件名（前端监听 .horse.settled）。
     */
    public function broadcastAs(): string
    {
        return 'horse.settled';
    }

    /**
     * 广播数据。
     *
     * @return array<string, mixed>
     */
    public function broadcastWith(): array
    {
        $config = GameConfig::forGame('horse_racing')?->params ?? [];
        $houseTake = (int) ($config['house_take_percent'] ?? 5);
        $seedPool = (int) ($config['seed_pool'] ?? 0);

        // 统计各马匹总下注，为前端还原个人分奖金额提供基础参数。
        $horsePools = HorseBet::query()
            ->where('race_id', $this->race->id)
            ->groupBy('horse_id')
            ->selectRaw('horse_id, SUM(amount) as pool')
            ->pluck('pool', 'horse_id')
            ->map(fn ($pool) => (int) $pool)
            ->toArray();

        $winnerPool = (int) ($horsePools[$this->race->winner_horse_id] ?? 0);
        $distributablePool = (int) round(
            HorseRace::calcDistributablePool($horsePools, $houseTake, $seedPool, $winnerPool)
        );

        // 找出获胜马匹的名称
        $horses = $this->race->horses ?? [];
        $winnerName = '未知';
        foreach ($horses as $horse) {
            if (($horse['id'] ?? 0) === $this->race->winner_horse_id) {
                $winnerName = ($horse['emoji'] ?? '').' '.($horse['name'] ?? '');
                break;
            }
        }

        return [
            'race_id' => $this->race->id,
            'winner_horse_id' => $this->race->winner_horse_id,
            'winner_name' => $winnerName,
            'total_pool' => (int) $this->race->total_pool,
            'winner_pool' => $winnerPool,
            'distributable_pool' => $distributablePool,
            'settled_at' => $this->race->settled_at?->toIso8601String(),
        ];
    }
}
