<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: your name
// +----------------------------------------------------------------------
namespace app\dice\logic\lottery_pool_config;

use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
use plugin\saiadmin\basic\think\BaseLogic;
use plugin\saiadmin\exception\ApiException;
use plugin\saiadmin\utils\Helper;
use support\think\Cache;

/**
 * 色子奖池配置逻辑层
 */
class DiceLotteryPoolConfigLogic extends BaseLogic
{
    /** Redis 当前彩金池（type=0 实例）key，无则按 type=0 创建 */
    private const REDIS_KEY_CURRENT_POOL = 'api:game:lottery_pool:default';

    private const EXPIRE = 86400 * 7;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->model = new DiceLotteryPoolConfig();
    }

    /**
     * 获取当前彩金池：从 Redis 读取实例，profit_amount 每次从 DB 实时读取以保证与抽奖累加一致
     *
     * @return array{id:int,name:string,safety_line:int,t1_weight:int,t2_weight:int,t3_weight:int,t4_weight:int,t5_weight:int,profit_amount:float}
     */
    public function getCurrentPool(): array
    {
        $cached = Cache::get(self::REDIS_KEY_CURRENT_POOL);
        if ($cached && is_string($cached)) {
            $data = json_decode($cached, true);
            if (is_array($data)) {
                $config = DiceLotteryPoolConfig::find($data['id'] ?? 0);
                $profit = 0.0;
                if ($config) {
                    $profit = isset($config->profit_amount) ? (float) $config->profit_amount : (isset($config->ev) ? (float) $config->ev : 0.0);
                } else {
                    $profit = (float) ($data['profit_amount'] ?? 0);
                }
                $data['profit_amount'] = $profit;
                return $data;
            }
        }
        $config = DiceLotteryPoolConfig::where('type', 0)->find();
        if (!$config) {
            throw new ApiException('未找到 type=0 的奖池配置，请先创建');
        }
        $row = $config->toArray();
        $profitAmount = isset($row['profit_amount']) ? (float) $row['profit_amount'] : (isset($row['ev']) ? (float) $row['ev'] : 0.0);
        $pool = [
            'id'            => (int) $row['id'],
            'name'          => (string) ($row['name'] ?? ''),
            'safety_line'   => (int) ($row['safety_line'] ?? 0),
            't1_weight'     => (int) ($row['t1_weight'] ?? 0),
            't2_weight'     => (int) ($row['t2_weight'] ?? 0),
            't3_weight'     => (int) ($row['t3_weight'] ?? 0),
            't4_weight'     => (int) ($row['t4_weight'] ?? 0),
            't5_weight'     => (int) ($row['t5_weight'] ?? 0),
            'profit_amount' => $profitAmount,
        ];
        Cache::set(self::REDIS_KEY_CURRENT_POOL, json_encode($pool), self::EXPIRE);
        return $pool;
    }

    /**
     * 更新当前彩金池：仅允许修改 safety_line、t1_weight～t5_weight，不修改 profit_amount
     * 同时更新 Redis 与 DB 中 type=0 的记录
     *
     * @param array{safety_line?:int,t1_weight?:int,t2_weight?:int,t3_weight?:int,t4_weight?:int,t5_weight?:int} $data
     */
    public function updateCurrentPool(array $data): void
    {
        $pool = $this->getCurrentPool();
        $id = (int) $pool['id'];
        $config = DiceLotteryPoolConfig::find($id);
        if (!$config) {
            throw new ApiException('奖池配置不存在');
        }
        $allow = ['safety_line', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight'];
        $update = [];
        foreach ($allow as $k) {
            if (array_key_exists($k, $data)) {
                if ($k === 'safety_line') {
                    $update[$k] = (int) $data[$k];
                } else {
                    $update[$k] = max(0, min(100, (int) $data[$k]));
                }
            }
        }
        if (empty($update)) {
            return;
        }
        DiceLotteryPoolConfig::where('id', $id)->update($update);
        $pool = array_merge($pool, $update);
        $refreshed = DiceLotteryPoolConfig::find($id);
        $pool['profit_amount'] = $refreshed && (isset($refreshed->profit_amount) || isset($refreshed->ev))
            ? (float) ($refreshed->profit_amount ?? $refreshed->ev)
            : (float) ($pool['profit_amount'] ?? 0);
        Cache::set(self::REDIS_KEY_CURRENT_POOL, json_encode($pool), self::EXPIRE);
    }
}
