<?php

declare(strict_types=1);

namespace app\common\service;

use app\common\library\game\StreakWinReward;
use support\think\Db;

/**
 * 对局维度统计：平台盈亏、中奖人数（与 GameLiveService 单号派彩口径一致）。
 */
final class GameRecordStatService
{
    /**
     * 根据注单与开奖号码回写 game_record 统计字段（已结束对局）。
     */
    public static function refreshForRecordId(int $recordId): void
    {
        if ($recordId <= 0) {
            return;
        }
        $record = Db::name('game_record')->where('id', $recordId)->find();
        if (!$record) {
            return;
        }
        $status = (int) ($record['status'] ?? 0);
        $now = time();

        if ($status !== 4) {
            Db::name('game_record')->where('id', $recordId)->update([
                'platform_profit_amount' => '0.00',
                'winner_user_count' => 0,
                'update_time' => $now,
            ]);
            GameHotDataCoordinator::afterGameRecordCommitted($recordId);

            return;
        }

        $resultRaw = $record['result_number'] ?? null;
        if ($resultRaw === null || $resultRaw === '') {
            return;
        }
        $resultNum = (int) $resultRaw;

        $bets = Db::name('bet_order')->where('period_id', $recordId)->select()->toArray();
        $totalBet = '0.00';
        $totalPayout = '0.00';
        $winnerUserIds = [];

        foreach ($bets as $bet) {
            $st = (int) ($bet['status'] ?? 0);
            if ($st === 3) {
                continue;
            }
            $tb = (string) ($bet['total_amount'] ?? '0');
            $totalBet = bcadd($totalBet, $tb, 2);

            if ($st === 2) {
                $payout = bcadd((string) ($bet['win_amount'] ?? '0'), (string) ($bet['jackpot_extra_amount'] ?? '0'), 2);
            } else {
                $payout = self::estimatePayoutForBet($bet, $resultNum);
            }

            $totalPayout = bcadd($totalPayout, $payout, 2);
            if (bccomp($payout, '0', 2) > 0) {
                $uid = (int) ($bet['user_id'] ?? 0);
                if ($uid > 0) {
                    $winnerUserIds[$uid] = true;
                }
            }
        }

        $profit = bcsub($totalBet, $totalPayout, 2);

        Db::name('game_record')->where('id', $recordId)->update([
            'platform_profit_amount' => $profit,
            'winner_user_count' => count($winnerUserIds),
            'update_time' => $now,
        ]);
        GameHotDataCoordinator::afterGameRecordCommitted($recordId);
    }

    /**
     * 与 GameLiveService::estimateLossForNumber 一致：命中号码时 total_amount × odds_factor。
     */
    private static function estimatePayoutForBet(array $bet, int $resultNumber): string
    {
        $pickNumbers = $bet['pick_numbers'] ?? null;
        if (is_string($pickNumbers)) {
            $decoded = json_decode($pickNumbers, true);
            $pickNumbers = is_array($decoded) ? $decoded : [];
        }
        if (!is_array($pickNumbers)) {
            $pickNumbers = [];
        }
        if (!in_array($resultNumber, array_map('intval', $pickNumbers), true)) {
            return '0.00';
        }
        $total = (string) ($bet['total_amount'] ?? '0');
        $streak = (int) ($bet['streak_at_bet'] ?? 0);
        $odds = StreakWinReward::totalOddsMultiplierForStreakAtBet($streak);

        return bcmul($total, $odds, 2);
    }
}
