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

use app\dice\helper\AdminScopeHelper;
use plugin\saiadmin\basic\BaseController;
use app\dice\logic\reward_config\DiceRewardConfigLogic;
use app\dice\logic\reward\DiceRewardLogic;
use app\dice\model\reward\DiceReward;
use app\dice\validate\reward_config\DiceRewardConfigValidate;
use plugin\saiadmin\service\Permission;
use support\Request;
use support\Response;

/**
 * 奖励配置控制器
 */
class DiceRewardConfigController extends BaseController
{
    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->logic = new DiceRewardConfigLogic();
        $this->validate = new DiceRewardConfigValidate;
        parent::__construct();
    }

    /**
     * 数据列表
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置列表', 'dice:reward_config:index:index')]
    public function index(Request $request): Response
    {
        $where = $request->more([
            ['grid_number_min', ''],
            ['grid_number_max', ''],
            ['ui_text', ''],
            ['real_ev_min', ''],
            ['real_ev_max', ''],
            ['tier', ''],
        ]);
        $query = $this->logic->search($where);
        AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $request->input('dept_id'));
        // 奖励索引 + 大奖权重共约 32 条，配置页需一次返回本渠道全部数据
        $data = $query->order('id', 'asc')->select()->toArray();
        return $this->success($data);
    }

    /**
     * 读取数据
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置读取', 'dice:reward_config:index:read')]
    public function read(Request $request): Response
    {
        $id = $request->input('id', '');
        $model = $this->logic->read($id);
        if ($model) {
            $data = is_array($model) ? $model : $model->toArray();
            return $this->success($data);
        } else {
            return $this->fail('not found');
        }
    }

    /**
     * 保存数据
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置添加', 'dice:reward_config:index:save')]
    public function save(Request $request): Response
    {
        $data = $request->post();
        $this->validate('save', $data);
        AdminScopeHelper::prepareConfigSaveData($data, $this->adminInfo ?? null, $request->input('dept_id'), $data);
        $result = $this->logic->add($data);
        if ($result) {
            return $this->success('add success');
        } else {
            return $this->fail('add failed');
        }
    }

    /**
     * 更新数据
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置修改', 'dice:reward_config:index:update')]
    public function update(Request $request): Response
    {
        $data = $request->post();
        if ($data === [] || $data === null) {
            $data = $request->all();
        }
        $this->validate('update', $data);
        $requestDeptId = AdminScopeHelper::pickRequestDeptId($request->input('dept_id'), is_array($data) ? $data : []);
        $model = $this->logic->read($data['id'] ?? 0);
        if ($model) {
            $recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
            if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $requestDeptId)) {
                return $this->fail('no permission to update this record');
            }
        }
        $result = $this->logic->edit($data['id'], $data, $this->adminInfo ?? null, $requestDeptId);
        if ($result) {
            return $this->success('update success');
        } else {
            return $this->fail('update failed');
        }
    }

    /**
     * 批量更新奖励索引配置（第一页：id、grid_number、ui_text、real_ev、tier、remark）
     * @param Request $request items: [{ id, grid_number?, ui_text?, real_ev?, tier?, remark? }, ...]
     * @return Response
     */
    #[Permission('修改奖励索引', 'dice:reward_config:index:batchUpdate')]
    public function batchUpdate(Request $request): Response
    {
        return $this->doBatchUpdateIndex($request);
    }

    /**
     * 按规则生成并保存奖励索引（需档位结算推荐配置权限，与 batchUpdate 写入逻辑相同）
     *
     * @param Request $request items: [{ id, grid_number?, ui_text?, ui_text_en?, real_ev?, tier?, remark? }, ...]
     */
    #[Permission('档位结算推荐配置', 'dice:reward_config:index:tierRecommend')]
    public function generateIndexByRules(Request $request): Response
    {
        return $this->doBatchUpdateIndex($request);
    }

    /**
     * @return Response
     */
    private function doBatchUpdateIndex(Request $request): Response
    {
        $items = $request->post('items', []);
        if (! is_array($items)) {
            return $this->fail('parameter items must be an array');
        }
        $err = $this->logic->validateBatchUpdateItems($items);
        if ($err !== null) {
            return $this->fail($err);
        }
        foreach ($items as $item) {
            $this->validate('batch_update', array_merge($item, ['id' => $item['id']]));
        }
        $requestDeptId = AdminScopeHelper::pickRequestDeptId($request->input('dept_id'), $request->post());
        $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $requestDeptId);
        $this->logic->batchUpdate($items, $deptId);
        return $this->success('save success');
    }

    /**
     * 删除数据
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置删除', 'dice:reward_config:index:destroy')]
    public function destroy(Request $request): Response
    {
        $ids = $request->post('ids', '');
        if (empty($ids)) {
            return $this->fail('please select data to delete');
        }
        $result = $this->logic->destroy($ids, $this->adminInfo ?? null, $request->input('dept_id'));
        if ($result) {
            return $this->success('delete success');
        } else {
            return $this->fail('delete failed');
        }
    }

    /**
     * T1-T5、BIGWIN 权重配比：按档位分组返回配置列表（含顺时针/逆时针权重，来自 dice_reward）
     * @param Request $request
     * @return Response
     */
    #[Permission('奖励配置列表', 'dice:reward_config:index:index')]
    public function weightRatioList(Request $request): Response
    {
        $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $request->input('dept_id'));
        DiceReward::refreshCache($deptId);
        $rewardLogic = new DiceRewardLogic();
        $data = $rewardLogic->getListGroupedByTierWithDirection($deptId);
        return $this->success($data);
    }

    /**
     * T1-T5、BIGWIN 权重配比：按 DiceReward 主键 id 批量更新 weight（写入 dice_reward，修改后刷新缓存）
     * items: [ { id: DiceReward.id, weight: 1-10000 }, ... ]
     * @param Request $request
     * @return Response
     */
    #[Permission('修改色子点数权重', 'dice:reward_config:index:batchUpdateWeights')]
    public function batchUpdateWeights(Request $request): Response
    {
        $items = $request->post('items', []);
        if (!is_array($items)) {
            return $this->fail('parameter items must be an array');
        }
        try {
            $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $request->input('dept_id'));
            $rewardLogic = new DiceRewardLogic();
            $rewardLogic->batchUpdateWeights($items, $deptId);
            return $this->success('save success');
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage());
        }
    }

    /**
     * 大奖权重：按 grid_number 批量保存 BIGWIN 权重（仅更新 dice_reward_config 表，不操作 dice_reward）
     * items: [ { grid_number: 5-30, weight: 0-10000 }, ... ]
     * @param Request $request
     * @return Response
     */
    #[Permission('大奖权重修改', 'dice:reward_config:index:saveBigwinWeightsByGrid')]
    public function saveBigwinWeightsByGrid(Request $request): Response
    {
        $items = $request->post('items', []);
        if (! is_array($items)) {
            return $this->fail('parameter items must be an array');
        }
        $err = $this->logic->validateBigwinWeightItems($items);
        if ($err !== null) {
            return $this->fail($err);
        }
        $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $request->input('dept_id'));
        $this->logic->batchUpdateBigwinWeight($items, $deptId);
        return $this->success('save success');
    }

    /**
     * 创建奖励对照：按当前 dice_reward_config 为两种方向（顺时针0、逆时针1）生成所有色子可能对应的 dice_reward 记录
     * 权重默认 1，可在「奖励对照」页的权重编辑弹窗中调整
     * @param Request $request
     * @return Response
     */
    #[Permission('创建奖励对照', 'dice:reward_config:index:createRewardReference')]
    public function createRewardReference(Request $request): Response
    {
        try {
            $rewardLogic = new DiceRewardLogic();
            $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $request->input('dept_id'));
            $result = $rewardLogic->createRewardReferenceFromConfig($deptId);
            return $this->success($result, 'create reward mapping success');
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage());
        }
    }

    /**
     * 创建奖励对照（预览）：不写入 dice_reward，仅计算并返回预览分组数据。
     * 若当前 dice_reward 与计算结果一致，则 unchanged=true，并在预览中复用现有权重（导入时仍沿用旧权重）。
     */
    #[Permission('创建奖励对照', 'dice:reward_config:index:createRewardReference')]
    public function createRewardReferencePreview(Request $request): Response
    {
        try {
            $rewardLogic = new DiceRewardLogic();
            $deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo ?? null, $request->input('dept_id'));
            $result = $rewardLogic->createRewardReferencePreviewFromConfig($deptId);
            return $this->success($result, 'preview reward mapping success');
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage());
        }
    }

    /**
     * 权重配比测试：仅模拟落点统计，不创建游玩记录。按当前配置在内存中模拟 N 次抽奖，返回各 grid_number 落点次数，可选保存到 dice_reward_config_record。
     * @param Request $request test_count: 100|500|1000, save_record: bool, lottery_config_id: int|null 奖池配置ID，用于设定 T1-T5 概率
     * @return Response
     */
    #[Permission('奖励配置列表', 'dice:reward_config:index:index')]
    public function runWeightTest(Request $request): Response
    {
        $testCount = (int) $request->post('test_count', 100);
        $saveRecord = (bool) $request->post('save_record', true);
        $adminId = isset($this->adminInfo['id']) ? (int) $this->adminInfo['id'] : null;
        $lotteryConfigId = $request->post('lottery_config_id', null);
        if ($lotteryConfigId !== null && $lotteryConfigId !== '') {
            $lotteryConfigId = (int) $lotteryConfigId;
        } else {
            $lotteryConfigId = null;
        }
        try {
            $result = $this->logic->runWeightTest($testCount, $saveRecord, $adminId, $lotteryConfigId);
            return $this->success($result);
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage());
        }
    }
}
