<?php

/**
 * 文件功能：游戏下注与奖励公屏右下角通知广播服务
 *
 * 统一处理百家乐、赛马、双色球等游戏下注或奖励领取成功后的公屏消息、
 * 右下角 Toast 通知载荷和异步落库，避免各玩法重复拼装广播结构。
 */

namespace App\Services;

use App\Events\MessageSent;
use App\Jobs\SaveMessageJob;

/**
 * 类功能：为游戏下注和奖励领取成功事件生成并广播全员可见通知。
 */
class GameBetBroadcastService
{
    public function __construct(
        private readonly ChatStateService $chatState,
    ) {}

    /**
     * 广播百家乐下注成功通知。
     */
    public function baccarat(int $roomId, string $username, int $amount, string $betLabel): void
    {
        $formattedAmount = number_format($amount);

        $this->pushBetMessage(
            roomId: $roomId,
            content: "🎲 <b>【百家乐】【{$username}】</b> 押注了 <b>{$formattedAmount}</b> 金币（{$betLabel}）！✨",
            fontColor: '#d97706',
            toastTitle: '🎲 有人下注百家乐',
            toastMessage: "<b>{$username}</b> 押注 <b>{$formattedAmount}</b> 金币（{$betLabel}）",
            toastIcon: '🎲',
            toastColor: '#d97706',
        );
    }

    /**
     * 广播赛马下注成功通知。
     */
    public function horseRace(int $roomId, string $username, int $amount, string $horseName): void
    {
        $formattedAmount = number_format($amount);

        $this->pushBetMessage(
            roomId: $roomId,
            content: "🐎 <b>【赛马】【{$username}】</b> 押注了 <b>{$formattedAmount}</b> 金币（{$horseName}）！✨",
            fontColor: '#d97706',
            toastTitle: '🐎 有人下注赛马',
            toastMessage: "<b>{$username}</b> 押注 <b>{$formattedAmount}</b> 金币（{$horseName}）",
            toastIcon: '🐎',
            toastColor: '#d97706',
        );
    }

    /**
     * 广播双色球购票成功通知。
     */
    public function lottery(int $roomId, string $username, string $issueNo, string $numbersLabel, int $ticketCount): void
    {
        $moreText = $ticketCount > 1 ? "等 {$ticketCount} 注号码" : '';

        $this->pushBetMessage(
            roomId: $roomId,
            content: "🎟️ 【{$username}】购买 {$issueNo} 期 {$numbersLabel} {$moreText}",
            fontColor: '#dc2626',
            toastTitle: '🎟️ 有人购买双色球',
            toastMessage: "<b>{$username}</b> 购买 {$issueNo} 期 {$numbersLabel} {$moreText}",
            toastIcon: '🎟️',
            toastColor: '#dc2626',
            action: '大声宣告',
        );
    }

    /**
     * 广播红包领取成功通知。
     */
    public function redPacketClaimed(int $roomId, string $username, int $amount, string $type): void
    {
        $typeLabel = $type === 'exp' ? '经验' : '金币';
        $typeIcon = $type === 'exp' ? '✨' : '💰';
        $toastColor = $type === 'exp' ? '#6d28d9' : '#d97706';
        $formattedAmount = number_format($amount);

        $this->pushBetMessage(
            roomId: $roomId,
            content: "🧧 <b>{$username}</b> 抢到了 <b>{$formattedAmount}</b> {$typeLabel}礼包！{$typeIcon}",
            fontColor: $toastColor,
            toastTitle: '🧧 有人领取红包',
            toastMessage: "<b>{$username}</b> 抢到 <b>{$formattedAmount}</b> {$typeLabel}礼包",
            toastIcon: '🧧',
            toastColor: $toastColor,
            toastActorUsername: $username,
            skipToastForActor: true,
        );
    }

    /**
     * 推送带右下角通知载荷的公屏游戏消息。
     */
    private function pushBetMessage(
        int $roomId,
        string $content,
        string $fontColor,
        string $toastTitle,
        string $toastMessage,
        string $toastIcon,
        string $toastColor,
        string $action = '',
        ?string $toastActorUsername = null,
        bool $skipToastForActor = false,
    ): void {
        $toastNotification = [
            'title' => $toastTitle,
            'message' => $toastMessage,
            'icon' => $toastIcon,
            'color' => $toastColor,
            'duration' => 8000,
        ];

        if ($toastActorUsername !== null) {
            // 记录触发人用于前端去重，避免本人同时看到本地到账提示和公屏领取提示。
            $toastNotification['actor_username'] = $toastActorUsername;
            $toastNotification['skip_for_actor'] = $skipToastForActor;
        }

        $message = [
            'id' => $this->chatState->nextMessageId($roomId),
            'room_id' => $roomId,
            'from_user' => '系统传音',
            'to_user' => '大家',
            'content' => $content,
            'is_secret' => false,
            'font_color' => $fontColor,
            'action' => $action,
            'sent_at' => now()->toDateTimeString(),
            'toast_notification' => $toastNotification,
        ];

        // 下注通知必须进房间 Presence 频道，确保当前房间所有在线人员都能看到右下角提示。
        $this->chatState->pushMessage($roomId, $message);
        event(new MessageSent($roomId, $message));
        SaveMessageJob::dispatch($message);
    }
}
