<?php

namespace App\Services;

use App\Game\Services\OuroGameService;
use App\Http\helper\NumConfig;
use App\Utility\SetNXLock;
use App\Util;
use Illuminate\Support\Facades\DB;

class HolidayWheelService
{
    /**
     * 获取节假日大转盘配置 + 用户状态
     */
    public function getWheelInfo(int $userId): array
    {
        $activity = DB::connection('write')
            ->table('agent.dbo.holiday_wheel_activity')
            ->orderBy('id', 'desc')
            ->first();

        $now = now();

        $status = 0;
        $startTime = null;
        $endTime = null;
        $logo = '';
        $button_url = '';
        $button_light_url = '';
        $lunzi_url = '';
        $dipan_url = '';
        // 默认规则从活动配置 + 商城档位中计算（包含金额、次数和档位信息）
        $rechargeRules = $this->getDefaultRechargeRules();

        if ($activity) {
            $status = (int)($activity->status ?? 0);
            $startTime = $activity->start_time;
            $endTime = $activity->end_time;
            $logo = $activity->icon_url ?? '';
            $button_url = $activity->button_url ?? '';
            $button_light_url = $activity->button_light_url ?? '';
            $lunzi_url = $activity->lunzi_url ?? '';
            $dipan_url = $activity->dipan_url ?? '';

            // 如果当前时间不在活动时间范围内，则前端状态强制视为关闭（0）
            if (!empty($startTime) && $now->lt($startTime)) {
                $status = 0;
            }
            if (!empty($endTime) && $now->gt($endTime)) {
                $status = 0;
            }
        }

        // 前端展示时只需要简单的奖励值数组，例如 [177, 1, 0.2, ...]，隐藏 slot_index 和 weight
        $slots = DB::connection('write')
            ->table('agent.dbo.holiday_wheel_config')
            ->orderBy('sort_index', 'asc')
            ->orderBy('slot_index', 'asc')
            ->pluck('reward')
            ->map(function ($reward) {
                return (float)$reward;
            })
            ->values()
            ->toArray();

        $userTimes = DB::connection('write')
            ->table('agent.dbo.holiday_wheel_user')
            ->where('UserID', $userId)
            ->first();

        $leftTimes = $userTimes ? (int)$userTimes->left_times : 0;
        $totalTimes = $userTimes ? (int)$userTimes->total_times : 0;

        return [
            'status' => $status,
            'start_time' => $startTime,
            'end_time' => $endTime,
            'logo_url' => $logo,
            'button_url' => $button_url,
            'button_light_url' => $button_light_url,
            'lunzi_url' => $lunzi_url,
            'dipan_url' => $dipan_url,

            'slots' => $slots,
            'user' => [
                'left_times' => $leftTimes,
                'total_times' => $totalTimes,
            ],
            'recharge_rules' => $rechargeRules,
            'now' => $now->toDateTimeString(),
        ];
    }

    /**
     * 充值赠送转盘次数（在充值成功后调用）
     * 有 gift_id=401 的充值添加次数
     */
    public function grantTimesOnRecharge(int $userId, float $payAmt, int $giftId = 0): void
    {
        if ($giftId != 401) {
            return;
        }

        $activity = DB::connection('write')
            ->table('agent.dbo.holiday_wheel_activity')
            ->orderBy('id', 'desc')
            ->first();

        if (!$activity || (int)$activity->status !== 1) {
            return;
        }

        $now = now();
        if (!empty($activity->start_time) && $now->lt($activity->start_time)) {
            return;
        }
        if (!empty($activity->end_time) && $now->gt($activity->end_time)) {
            return;
        }

        // 统一使用默认规则（已基于活动配置 + 商城档位计算），保持金额与 times 一致
        $rules = $this->getDefaultRechargeRules();

        $payStr = number_format($payAmt, 2, '.', '');
        $addTimes = 0;
        foreach ($rules as $rule) {
            $amount = isset($rule['amount']) ? number_format($rule['amount'], 2, '.', '') : null;
            $times = (int)($rule['times'] ?? 0);
            if ($amount !== null && $amount === $payStr && $times > 0) {
                $addTimes += $times;
            }
        }

        if ($addTimes <= 0) {
            return;
        }

        DB::connection('write')->transaction(function () use ($userId, $addTimes) {
            $row = DB::connection('write')
                ->table('agent.dbo.holiday_wheel_user')
                ->where('UserID', $userId)
                ->lockForUpdate()
                ->first();

            if ($row) {
                DB::connection('write')
                    ->table('agent.dbo.holiday_wheel_user')
                    ->where('UserID', $userId)
                    ->update([
                        'left_times' => (int)$row->left_times + $addTimes,
                        'total_times' => (int)$row->total_times + $addTimes,
                        'updated_at' => now(),
                    ]);
            } else {
                DB::connection('write')
                    ->table('agent.dbo.holiday_wheel_user')
                    ->insert([
                        'UserID' => $userId,
                        'left_times' => $addTimes,
                        'total_times' => $addTimes,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
            }
        });
    }

    /**
     * 执行一次转盘抽奖
     */
    public function spin(int $userId): array
    {
        $redisKey = 'holiday_wheel_spin_' . $userId;
        $lock = SetNXLock::getExclusiveLock($redisKey, 5);
        if (!$lock) {
            return [
                'error' => ['web.activity.wheel_too_frequent', __('messages.web.activity.wheel_too_frequent')],
            ];
        }

        try {
            $activity = DB::connection('write')
                ->table('agent.dbo.holiday_wheel_activity')
                ->orderBy('id', 'desc')
                ->first();

            if (!$activity || (int)$activity->status !== 1) {
                return [
                    'error' => ['web.activity.wheel_not_open', __('messages.web.activity.wheel_not_open')],
                ];
            }

            $now = now();
            if (!empty($activity->start_time) && $now->lt($activity->start_time)) {
                return [
                    'error' => ['web.activity.wheel_not_started', __('messages.web.activity.wheel_not_started')],
                ];
            }
            if (!empty($activity->end_time) && $now->gt($activity->end_time)) {
                return [
                    'error' => ['web.activity.wheel_ended', __('messages.web.activity.wheel_ended')],
                ];
            }

            $slots = DB::connection('write')
                ->table('agent.dbo.holiday_wheel_config')
                ->orderBy('sort_index', 'asc')
                ->orderBy('slot_index', 'asc')
                ->get();

            if ($slots->isEmpty()) {
                return [
                    'error' => ['web.activity.wheel_config_missing', __('messages.web.activity.wheel_config_missing')],
                ];
            }

            DB::connection('write')->beginTransaction();

            $userRow = DB::connection('write')
                ->table('agent.dbo.holiday_wheel_user')
                ->where('UserID', $userId)
                ->lockForUpdate()
                ->first();

            if (!$userRow || (int)$userRow->left_times <= 0) {
                DB::connection('write')->rollBack();
                return [
                    'error' => ['web.activity.wheel_no_times', __('messages.web.activity.wheel_no_times')],
                ];
            }

            $totalWeight = 0;
            $weights = [];
            foreach ($slots as $slot) {
                $w = (int)$slot->weight;
                if ($w < 0) {
                    $w = 0;
                }
                $weights[] = $w;
                $totalWeight += $w;
            }

            if ($totalWeight <= 0) {
                DB::connection('write')->rollBack();
                return [
                    'error' => ['web.activity.wheel_weight_error', __('messages.web.activity.wheel_weight_error')],
                ];
            }

            $rand = mt_rand(1, $totalWeight);
            $cumulative = 0;
            $selectedIndex = 0;
            foreach ($slots as $idx => $slot) {
                $cumulative += $weights[$idx];
                if ($rand <= $cumulative) {
                    $selectedIndex = $idx;
                    break;
                }
            }

            $selectedSlot = $slots[$selectedIndex];
            $reward = (float)$selectedSlot->reward;
            $slotIndex = (int)$selectedSlot->slot_index;

            DB::connection('write')
                ->table('agent.dbo.holiday_wheel_user')
                ->where('UserID', $userId)
                ->update([
                    'left_times' => (int)$userRow->left_times - 1,
                    'updated_at' => now(),
                ]);

            DB::connection('write')
                ->table('agent.dbo.holiday_wheel_history')
                ->insert([
                    'UserID' => $userId,
                    'slot_index' => $slotIndex,
                    'reward' => $reward,
                    'created_at' => now(),
                ]);

            DB::connection('write')->commit();

            OuroGameService::AddScore($userId,$reward*NumConfig::NUM_VALUE,110,false);

            return [
                'slot_index' => $slotIndex,
                'reward' => $reward,
                'left_times' => (int)$userRow->left_times - 1,
            ];
        } catch (\Throwable $e) {
            DB::connection('write')->rollBack();
            throw $e;
        } finally {
            SetNXLock::release($redisKey);
        }
    }

    /**
     * 默认充值规则：
     * - 基于固定金额和次数：[9.99=>1次, 19.99=>3次, 49.99=>6次]
     * - 额外从 recharge_gear 中取出相同金额的档位详情（类似商城列表的数据），
     *   times 字段保持不变。
     */
    public function getDefaultRechargeRules(): array
    {
        // 固定的基础规则（金额+次数）
        // 1) 先从活动配置中读取 recharge_rules
        $rules = [];
        $activity = DB::connection('write')
            ->table('agent.dbo.holiday_wheel_activity')
            ->orderBy('id', 'desc')
            ->first();

        if ($activity && !empty($activity->recharge_rules)) {
            $decoded = json_decode($activity->recharge_rules, true);
            if (is_array($decoded)) {
                $rules = $decoded;
            }
        }

        // 2) 如果没有配置，则使用默认规则
        if (empty($rules)) {
            $rules = [
                ['amount' => 9.99, 'times' => 1],
                ['amount' => 19.99, 'times' => 3],
                ['amount' => 19.99, 'times' => 3],
                ['amount' => 49.99, 'times' => 6],
            ];
        }

        // 为每条规则附加与金额相同的 recharge_gear 配置（类似商城 gear 列表）
        foreach ($rules as &$rule) {
            $amount = $rule['amount'];

            $item = DB::connection('write')
                ->table('agent.dbo.recharge_gear')
                ->where('status', 1)
//                ->where('in_shop', 1)
                ->where('money', $amount)
                ->select('id', 'money', 'favorable_price', 'give', 'recommend', 'gear')
                ->orderBy('id', 'asc')
                ->first();

            if ($item) {
                // 过滤 gear 支付方式，跟商城接口一致
                if (!empty($item->gear)) {
                    $item->gear = Util::filterGearByDevice($item->gear);
                }

                $rule['gear'] = [
                    'id' => $item->id,
                    'money' => (float)$item->money,
                    'favorable_price' => (float)$item->favorable_price,
                    'give' => (float)$item->give,
                    'recommend' => (int)($item->recommend ?? 0),
                    'gear' => $item->gear,
                    'gift_id' => 401,
                ];
            } else {
                $rule['gear'] = null;
            }
        }
        unset($rule);

        return $rules;
    }
}

