<?php

namespace App\Http\Controllers\admin;

use Illuminate\Http\JsonResponse;
use App\Constants\HttpStatus;
use App\Http\Controllers\Controller;
use App\Models\Config as ConfigModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Exception;
use Telegram\Bot\Api;
use Telegram\Bot\Exceptions\TelegramSDKException;
use Telegram\Bot\FileUpload\InputFile;
use App\Services\ConfigService;

class Config extends Controller
{

    /** 设置配置
     */
    public function setField()
    {
        try {
            $params = request()->validate([
                'field' => ['required', 'string', 'max:255'],
                'val' => ['nullable'],
                'remark' => ['nullable'],
            ]);
            $val = $params['val'] ?? '';
            $update_data=[
                'val' => $val,
            ];
            if (isset($params['remark'])) {
                $update_data['remark'] = $params['remark'];
            }
            ConfigModel::updateOrCreate(['field' => $params['field']], $update_data);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success();
    }

    /**
     * @api {post} /admin/config/pc28Switch 游戏切换(0:pc28 1:急速28)
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     *
     * @apiParam {int=0,1} val  (0:pc28 1:极速28)
     */
    public function pc28Switch()
    {
        try {
            $params = request()->validate([
                'val' => ['required', 'integer', 'min:0', 'in:0,1']
            ]);
            ConfigModel::updateOrCreate(['field' => 'pc28_switch'], ['val' => $params['val']]);
            Cache::put('pc28_switch', $params['val']);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success();
    }

    /**
     * @api {get} /admin/config/pcConfig 极速PC28相关配置
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     *
     * @apiParam {int} [page=1]
     * @apiParam {int} [limit=15]
     */
    public function pcConfig(): JsonResponse
    {
        try {
            $search['group_id'] = 4;
            $result = ConfigService::paginate($search);
            foreach ($result['data'] as $item) {
                if ($item['field'] == 'pc28_switch') {
                    $item['val'] = Cache::get('pc28_switch', $item['val']);
                }
            }
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
        } catch
        (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success($result);
    }

    /**
     * @api {get} /admin/config/gameList 彩票配置
     */
    public function gameList(): JsonResponse
    {
        try {
            $search['group_id'] = 5;
            $list = ConfigModel::where('group_id', $search['group_id'])->where('field', 'game_list')->value('val');
            $list = $list ? json_decode($list, true) : [];
            $data = [];
            $i = count($list);
            foreach($list as $v) {
                $i--;
                $temp_key = $v['sort']*10+$i;
                $data[$temp_key] = $v;
            }
            krsort($data);
            $data = array_values($data);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
        } catch
        (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success($data);
    }

    /**
     *  分页数据
     *
     */
    function index()
    {
        try {
            request()->validate([
                'field' => ['nullable', 'string'],
                'id' => ['nullable', 'string'],
            ]);
            $search = request()->all();
            $search['in_group_id'] = [1, 3];
            $result = ConfigService::paginate($search);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success($result);
    }

    /**
     *  修改|新增
     *
     */
    public
    function store()
    {
        try {
            $id = request()->post('id', '');
            if ($id) {
                $validator = [
                    'id' => ['required', 'integer', 'min:1'],
                    'val' => ['required', 'string'],
                    'remark' => 'required|nullable|string',
                ];
            } else {
                $validator = [
                    'field' => 'required|string|max:50|alpha_dash|unique:config,field',
                    'val' => 'required|string',
                    'remark' => 'required|nullable|string',
                ];
                $field = request()->input("field", 'aaa');
                switch ($field) {
                    case 'group_language':
                        $validator['val'] = ['required', 'string', 'in:zh,vi,en'];
                        break;
                    case 'pc28_switch':
                        $validator['val'] = ['required', 'integer', 'in:0,1'];
                        break;
                    case 'pc28_time':
                        //格式如：09:00-21:00
                        $validator['val'] = ['nullable', 'string', 'regex:/^\d{2}:\d{2}-\d{2}:\d{2}$/i'];
                        break;
                }


            }


            $params = request()->validate($validator);
            if (!isset($params['id'])) $params['group_id'] = 3;


            $ret = ConfigService::submit($params);
            if ($ret['code'] == ConfigService::NOT) {
                throw new Exception(HttpStatus::CUSTOM_ERROR, $ret['code']);
            }
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success([], $ret['msg']);

    }

    /**
     *  删除
     */
    public
    function destroy()
    {

        $id = request()->post('id');
        // 示例：通过 ID 删除
        $info = ConfigService::findOne(['id' => $id]);
        if (!$info) {
            return $this->error(HttpStatus::CUSTOM_ERROR, '配置不存在');
        }
        if ($info->group_id !== 3) {
            return $this->error(HttpStatus::CUSTOM_ERROR, '禁止删除');
        }
        $info->delete();
        return $this->success([], '删除成功');
    }

    /**
     * @api {get} /admin/config/get 获取指定配置
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     *
     * @apiParam {string} field 配置项
     * - base_score 房间底分数组
     * - brokerage 抽佣比例
     * - service_charge 提现手续费
     * - service_account 客服账号
     * - receiving_address 手动收款 的地址
     * - receiving_type 收款方式 1-自动 2-手动
     * - channel_message 频道消息
     *
     * @apiSuccess (data) {Object} data
     * @apiSuccess (data) {int[]} [data.base_score] 房间底分数组
     * @apiSuccess (data) {float} [data.brokerage] 抽佣比例
     * @apiSuccess (data) {int} [data.service_charge] 提现手续费
     * @apiSuccess (data) {string} [data.service_account] 客服账号
     * @apiSuccess (data) {string} [data.receiving_address] 手动收款 的地址
     * @apiSuccess (data) {int} [data.receiving_type] 收款方式 1-自动 2-手动
     * @apiSuccess (data) {Object} [data.channel_message] 频道消息
     * @apiSuccess (data) {string} data.channel_message.chatId 频道账号或频道ID
     * @apiSuccess (data) {string} data.channel_message.image 要发送频道消息 的图片URL
     * @apiSuccess (data) {string} data.channel_message.text 要发送频道消息文 的本内容
     * @apiSuccess (data) {array} data.channel_message.button 要发送频道消息 的内联按钮，具体结构见下方
     * @apiSuccessExample {js} 内联按钮结构
     * //button 的数据格式如下
     * [
     *   [      //第一行
     *     {    //第一行按钮 的第一个按钮
     *       "text": "百度",  //按钮文字
     *       "url": "https://baidu.com"   //按钮跳转的链接
     *     },
     *     {    //第一行按钮 的第二个按钮
     *       "text": "百度",
     *       "url": "https://baidu.com"
     *     }
     *     //更多按钮...
     *   ],
     *   [    //第二行
     *     {
     *       "text": "百度",
     *       "url": "https://baidu.com"
     *     }
     *   ]
     *   //更多行...
     * ]
     *
     */
    public function get()
    {
        try {
            request()->validate([
                'field' => ['required', 'string', 'min:1'],
            ]);
            $field = request()->input('field');
            $config = ConfigModel::where('field', $field)->first();
            $res = [];
            if ($config) {
                $val = $config->val;
                switch ($field) {
                    case "channel_message":
                    case "base_score":
                        $val = json_decode($config->val);
                        break;
                    case "brokerage":
                    case "service_charge":
                        $val = floatval($config->val);
                        break;
                }
                $res[$field] = $val;
            }
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(intval($e->getCode()));
        }
        return $this->success($res);
    }


    /**
     * @api {get} /admin/config/getAll 获取所有配置
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     */
    public
    function getAll()
    {
        $list = ConfigModel::where('id', '>', 0)->get();
        $arr = [];
        foreach ($list as $item) {
            $val = $item['val'];
            switch ($item['field']) {
                case "channel_message":
                case "base_score":
                    $val = json_decode($item['val'], true);
                    break;
                case "brokerage":
                case "service_charge":
                    $val = floatval($item['val']);
                    break;
            }
            $arr[$item['field']] = $val;
        }
        return $this->success($arr);
    }

    /**
     * @api {post} /admin/config/sendChannelMessage 发送频道消息
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     * @apiDescription 该接口会保存配置，并发送频道消息； 创建频道之后需要将 bot 拉进频道内，然后将 bot 设置为管理员
     *
     *
     * @apiParam {String} chatId 频道的username - 创建频道时候填写的 username
     * @apiParam {String} type 发送的类型 - image：图片 - video：视频
     * @apiParam {String} image 要发送的图片
     * @apiParam {String} text 要发送的文字
     * @apiParam {Array} button 消息中的按钮 具体结构请看示例代码
     * @apiParam {String} video 视频
     * @apiParam {String} video_caption 视频文案
     * @apiParam {Boolean} [isSend=true] 是否发送
     * @apiParam {Boolean} [isTop=true] 是否置顶
     */
    public function sendChannelMessage()
    {
        set_time_limit(0);
        DB::beginTransaction();
        try {

            $validate = [
                'chatId' => ['required', 'string', 'min:1'],
                'type' => ['required', 'string', 'in:image,video,text'],
                'text' => ['nullable', 'string'],
                'isSend' => ['nullable', 'boolean'],
                'isTop' => ['nullable', 'boolean'],
                'button' => ['array'],
                'button.*' => ['required', 'array'],
                'button.*.*.text' => ['required', 'string'],
                'button.*.*.url' => ['required', 'url'],
            ];
            $type = request()->input('type');
            if (in_array($type, ['image', 'video'])) $validate[$type] = ['required', 'url'];
            $params = request()->validate($validate);
            $params['image'] = request()->input('image', '');
            $params['video'] = request()->input('video', '');
            $isSend = request()->input('isSend', false);
            $isTop = request()->input('isTop', false);
            unset($params['isTop'], $params['isSend']);
            ConfigModel::where('field', 'channel_message')->update(['val' => json_encode($params)]);
            DB::commit();
        } catch (ValidationException $e) {
            DB::rollBack();
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error(intval($e->getCode()), $e->getMessage());
        }

        if ($isSend) {
            try {
                $config = ConfigModel::where('field', 'channel_message')->first()->val;
                $config = json_decode($config, true);
                $telegram = new Api(config('services.telegram.token'));
                $msg = [];
                $msg['chat_id'] = "@{$config['chatId']}";
                $msg['protect_content'] = false;
                if (!empty($config['button'])) {
                    $msg['reply_markup'] = json_encode(['inline_keyboard' => $config['button']]);
                }

                switch ($type) {
                    case 'image':
                        $msg['photo'] = InputFile::create($config['image']);
                        $msg['caption'] = $config['text'];
                        $response = $telegram->sendPhoto($msg);
                        break;
                    case 'video':
                        $msg['video'] = InputFile::create($config['video']);
                        $msg['caption'] = $config['text'];
                        $response = $telegram->sendVideo($msg);
                        break;
                    case 'text':
                        $msg['text'] = $config['text'];
                        $response = $telegram->sendMessage($msg);
                        break;
                    default:
                        throw new Exception("保存成功，发送失败", HttpStatus::CUSTOM_ERROR);
                }
                // 置顶消息
                if ($isTop) {
                    $messageId = $response->get('message_id');
                    $telegram->pinChatMessage(['chat_id' => "@{$config['chatId']}", 'message_id' => $messageId]);
                }
            } catch (TelegramSDKException $e) {
                return $this->error(HttpStatus::CUSTOM_ERROR, '保存成功，发送失败', $e->getMessage());
            } catch (Exception $e) {
                return $this->error($e->getCode(), '保存成功，发送失败');
            }
        }
        return $this->success();
    }

    /**
     * @api {post} /admin/config/set 修改配置
     * @apiGroup 配置
     * @apiUse result
     * @apiUse header
     * @apiVersion 1.0.0
     *
     * @apiParam {int[]} base_score 房间底分数组
     * @apiParam {string} brokerage 抽佣比例
     * @apiParam {string} service_charge 提现手续费
     * @apiParam {string} service_account 客服账号
     * @apiParam {string} receiving_address 充值收款地址
     * @apiParam {string} receiving_type 收款方式 1-自动 2-手动
     *
     */
    public function set()
    {
        DB::beginTransaction();
        try {
            request()->validate([
                'base_score' => ['required', 'array', 'min:1', 'max:30'],
                'base_score.*' => ['integer', 'min:1'],
                'brokerage' => ['required', 'numeric', 'min:0.01', 'max:1', 'regex:/^\d*(\.\d{1,2})?$/'],
                'service_charge' => ['required', 'integer', 'min:1'],
                'service_account' => ['required', 'string', 'min:1'],
                'receiving_address' => ['required', 'string', 'min:34'],
                'receiving_type' => ['required', 'integer', 'in:1,2']
            ]);
            $baseScore = request()->input('base_score');
            sort($baseScore);
            $baseScore = array_unique($baseScore);
            ConfigModel::where('field', 'base_score')
                ->update(['val' => json_encode($baseScore)]);

            $val = request()->input('brokerage');
            ConfigModel::where('field', 'brokerage')
                ->update(['val' => $val]);
            $val = request()->input('service_charge');
            ConfigModel::where('field', 'service_charge')
                ->update(['val' => $val]);

            $val = request()->input('service_account');
            ConfigModel::where('field', 'service_account')
                ->update(['val' => $val]);

            $val = request()->input('receiving_address');
            ConfigModel::where('field', 'receiving_address')
                ->update(['val' => $val]);

            $val = request()->input('receiving_type');
            ConfigModel::where('field', 'receiving_type')
                ->update(['val' => $val]);

            DB::commit();
        } catch (ValidationException $e) {
            DB::rollBack();
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error(intval($e->getCode()), $e->getMessage());
        }
        return $this->success();
    }
}