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

use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
use app\dice\model\player\DicePlayer;
use app\dice\model\reward\DiceRewardConfig;
use app\dice\model\DiceModel;
use think\model\relation\BelongsTo;

/**
 * 玩家抽奖记录模型
 *
 * dice_play_record 玩家抽奖记录
 *
 * @property  $id ID
 * @property  $player_id 玩家id
 * @property  $admin_id 关联玩家所属管理员ID（DicePlayer.admin_id）
 * @property  $lottery_config_id 彩金池配置
 * @property  $lottery_type 抽奖类型
 * @property  $ante 底注/注数（dice_ante_config.mult）
 * @property  $paid_amount 付费金额（付费局=ante*1，免费局=0）
 * @property  $is_win 是否中大奖：豹子号[1,1,1,1,1]~[6,6,6,6,6]为1，否则0
 * @property  $win_coin 赢取平台币（= super_win_coin + reward_win_coin）
 * @property  $super_win_coin 中大奖平台币（豹子时发放）
 * @property  $reward_win_coin 摇色子中奖平台币
 * @property  $use_coins 消耗平台币（兼容字段：付费局=paid_amount，免费局=0）
 * @property  $direction 方向:0=顺时针,1=逆时针
 * @property  $reward_tier 中奖档位：T1,T2,T3,T4,T5,BIGWIN
 * @property  $remark 备注（如惩罚格余额不足）
 * @property  $lottery_id 奖池
 * @property  $start_index 起始索引
 * @property  $target_index 结束索引
 * @property  $roll_array 摇取点数，格式:[1,2,3,4,5]（5个点数）
 * @property  $roll_number 摇取点数和（5个色子点数之和，5-30）
 * @property  $lottery_name 奖池名
 * @property  $status 状态:0=超时/失败 1=成功
 * @property  $create_time 创建时间
 * @property  $update_time 修改时间
 */
class DicePlayRecord extends DiceModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 数据库表名称
     * @var string
     */
    protected $table = 'dice_play_record';

    /**
     * 玩家
     * 关联模型 dicePlayer
     */
    public function dicePlayer(): BelongsTo
    {
        return $this->belongsTo(DicePlayer::class, 'player_id', 'id');
    }

    /**
     * 彩金池配置
     * 关联模型 diceLotteryPoolConfig
     */
    public function diceLotteryPoolConfig(): BelongsTo
    {
        return $this->belongsTo(DiceLotteryPoolConfig::class, 'lottery_config_id', 'id');
    }

    /** 按玩家用户名模糊（dicePlayer.username） */
    public function searchUsernameAttr($query, $value)
    {
        if ($value === '' || $value === null) {
            return;
        }
        $ids = DicePlayer::where('username', 'like', '%' . $value . '%')->column('id');
        if (!empty($ids)) {
            $query->whereIn('player_id', $ids);
        } else {
            $query->whereRaw('1=0');
        }
    }

    /** 按彩金池奖池名称或内部标识模糊搜索 */
    public function searchLotteryConfigNameAttr($query, $value)
    {
        if ($value === '' || $value === null) {
            return;
        }
        $like = '%' . $value . '%';
        $ids = DiceLotteryPoolConfig::where(function ($q) use ($like) {
            $q->where('name', 'like', $like)
                ->whereOr('remark', 'like', $like);
        })->column('id');
        if (!empty($ids)) {
            $query->whereIn('lottery_config_id', $ids);
        } else {
            $query->whereRaw('1=0');
        }
    }

    /**
     * 读取 roll_array 时：若为空且 roll_number 在 5～30，则按点数和生成默认 5 个色子数组，避免“点数和有值但五个点数空”的展示问题
     * @param mixed $value 库中原始值（JSON 字符串或 null）
     * @param array $data 当前记录数据
     * @return array 5 个元素的数组，每项 1～6
     */
    public function getRollArrayAttr($value, $data = []): array
    {
        $arr = [];
        if (is_string($value) && $value !== '') {
            $decoded = json_decode($value, true);
            $arr = is_array($decoded) ? $decoded : [];
        } elseif (is_array($value)) {
            $arr = $value;
        }
        $sum = isset($data['roll_number']) ? (int) $data['roll_number'] : 0;
        if (count($arr) === 5 && array_sum($arr) === $sum) {
            $valid = true;
            foreach ($arr as $v) {
                if (!is_numeric($v) || (int) $v < 1 || (int) $v > 6) {
                    $valid = false;
                    break;
                }
            }
            if ($valid) {
                return array_map('intval', array_slice($arr, 0, 5));
            }
        }
        if ($sum >= 5 && $sum <= 30) {
            return self::defaultRollArrayForSum($sum);
        }
        return array_slice(array_map('intval', $arr), 0, 5);
    }

    /**
     * 根据点数和生成默认 5 个色子数组（每项 1～6），用于补全缺失的 roll_array
     */
    public static function defaultRollArrayForSum(int $sum): array
    {
        $sum = max(5, min(30, $sum));
        $base = (int) floor($sum / 5);
        $rem = $sum - 5 * $base;
        $arr = array_fill(0, 5, $base);
        for ($i = 0; $i < $rem; $i++) {
            $arr[$i]++;
        }
        $arr = array_map(function ($v) {
            return max(1, min(6, (int) $v));
        }, $arr);
        return array_values($arr);
    }

    /** 抽奖类型 */
    public function searchLotteryTypeAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('lottery_type', '=', $value);
        }
    }

    /**
     * 是否豹子号（中大奖）：5 个点数相同且为 1~6 之一（含 [6,6,6,6,6]）
     * @param int[] $rollArray 摇取点数数组，如 [1,1,1,1,1] 或 [6,6,6,6,6]
     * @return bool
     */
    public static function isSuperWin(array $rollArray): bool
    {
        if (count($rollArray) !== 5) {
            return false;
        }
        $unique = array_unique($rollArray);
        if (count($unique) !== 1) {
            return false;
        }
        $value = reset($unique);
        return in_array($value, [1, 2, 3, 4, 5, 6], true);
    }

    /** 是否中大奖 */
    public function searchIsWinAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('is_win', '=', $value);
        }
    }

    /** 赢取平台币下限 */
    public function searchWinCoinMinAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('win_coin', '>=', $value);
        }
    }

    /** 赢取平台币上限 */
    public function searchWinCoinMaxAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('win_coin', '<=', $value);
        }
    }

    /** 中大奖平台币下限 */
    public function searchSuperWinCoinMinAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('super_win_coin', '>=', $value);
        }
    }

    /** 中大奖平台币上限 */
    public function searchSuperWinCoinMaxAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('super_win_coin', '<=', $value);
        }
    }

    /** 摇色子中奖平台币下限 */
    public function searchRewardWinCoinMinAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('reward_win_coin', '>=', $value);
        }
    }

    /** 摇色子中奖平台币上限 */
    public function searchRewardWinCoinMaxAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('reward_win_coin', '<=', $value);
        }
    }

    /** 按奖励配置前端显示文本模糊（diceRewardConfig.ui_text） */
    public function searchRewardUiTextAttr($query, $value)
    {
        if ($value === '' || $value === null) {
            return;
        }
        $ids = DiceRewardConfig::where('ui_text', 'like', '%' . $value . '%')->column('id');
        if (!empty($ids)) {
            $query->whereIn('target_index', $ids);
        } else {
            $query->whereRaw('1=0');
        }
    }

    /** 按奖励档位（表字段 reward_tier，中奖名 T1-T5/BIGWIN） */
    public function searchRewardTierAttr($query, $value)
    {
        if ($value === '' || $value === null) {
            return;
        }
        $query->where('reward_tier', '=', $value);
    }

    /** 方向 0=顺时针 1=逆时针 */
    public function searchDirectionAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('direction', '=', $value);
        }
    }

    /** 摇取点数和下限 */
    public function searchRollNumberMinAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('roll_number', '>=', $value);
        }
    }

    /** 摇取点数和上限 */
    public function searchRollNumberMaxAttr($query, $value)
    {
        if ($value !== '' && $value !== null) {
            $query->where('roll_number', '<=', $value);
        }
    }
}
