<?php

use addons\webman\Admin;
use addons\webman\model\AdminUser;
use addons\webman\model\Player;
use addons\webman\model\PlayerDeliveryRecord;
use addons\webman\model\PlayerMoneyEditLog;
use addons\webman\model\PlayerPlatformCash;
use addons\webman\validator\ValidatorFactory;

if (!function_exists('admin_sysconf')) {

    /**
     * 配置系统参数
     * @param string|null $name 参数名称
     * @param string|null $value 无值为获取
     * @return mixed
     */
    function admin_sysconf(string $name = null, string $value = null)
    {
        $model = plugin()->webman->config('database.config_model');
        if (is_null($name)) {
            return $model::get()->toArray();
        }
        if (is_null($value)) {
            $value = $model::where('name', $name)->value('value');
            if (is_null($value)) {
                return $value;
            };
            $json = json_decode($value, true);
            if (is_array($json)) {
                return $json;
            } else {
                return $value;
            }
        } else {
            if (is_array($value)) {
                $value = json_encode($value, JSON_UNESCAPED_UNICODE);
            }
            return $model::updateOrCreate(['name' => $name], ['value' => $value]);
        }
    }
}

if (!function_exists('validator')) {
    /**
     * Create a new Validator instance.
     *
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     * @return ValidatorFactory
     */
    function validator(array $data = [], array $rules = [], array $messages = [], array $customAttributes = [])
    {
        $factory = new ValidatorFactory();
        if (func_num_args() === 0) {
            return $factory;
        }
        $factory->setPresenceVerifier(new \Illuminate\Validation\DatabasePresenceVerifier(\Illuminate\Database\Eloquent\Model::getConnectionResolver()));

        return $factory->make($data, $rules, $messages, $customAttributes);
    }
}

if (!function_exists('getGameTypeCateName')) {
    /**
     * 获取游戏类型转义名称
     * @param $val
     * @return string
     */
    function getGameTypeCateName($val): string
    {
        return admin_trans('game_type.game_type_cate.' . $val);
    }
}

if (!function_exists('floorToCoinsSecond')) {
    function floorToCoinsSecond($number)
    {
        if (!is_numeric($number)) {
            return $number;
        }

        return number_format(($number * 100) / 100, 2);
    }
}

if (!function_exists('playerManualSystem')) {
    /**
     * 系统加点
     * @param $data
     * @throws Exception
     */
    function playerManualSystem($data)
    {
        $money = (float)$data['money'];
        if ($money <= 0) {
            throw new Exception(admin_trans('player.wallet.operation_amount_error'));
        }
        if ($data['type'] == PlayerMoneyEditLog::TYPE_INCREASE) {
            if (!in_array($data['increase_action'], [
                PlayerMoneyEditLog::ACTIVITY_GIVE,
                PlayerMoneyEditLog::RECHARGE,
                PlayerMoneyEditLog::VIP_RECHARGE,
                PlayerMoneyEditLog::OTHER,
                PlayerMoneyEditLog::ADMIN_INCREASE
            ])) {
                throw new Exception(admin_trans('player.wallet.wallet_type_error'));
            }
            $action = $data['increase_action'];
        } else {
            if ($data['deduct_action'] != PlayerMoneyEditLog::ADMIN_DEDUCT) {
                throw new Exception(admin_trans('player.wallet.wallet_type_error'));
            }
            $action = $data['deduct_action'];
        }
        /** @var Player $player */
        $player = Player::find($data['id']);
        $tradeno = date('YmdHis') . rand(10000, 99999);
        $originMoney = $player->wallet->money;

        $playerMoneyEditLog = new PlayerMoneyEditLog;
        $playerMoneyEditLog->player_id = $player->id;
        $playerMoneyEditLog->department_id = $player->department_id;
        $playerMoneyEditLog->type = $data['type'];
        $playerMoneyEditLog->action = $action;
        $playerMoneyEditLog->tradeno = $tradeno;
        $playerMoneyEditLog->currency = $player->currency;
        $playerMoneyEditLog->money = $money;
        $playerMoneyEditLog->inmoney = $money;
        $playerMoneyEditLog->remark = $data['remark'];
        $playerMoneyEditLog->user_id = Admin::id() ?? 0;
        $playerMoneyEditLog->user_name = !empty(Admin::user()) ? Admin::user()->toArray()['username'] : trans('system_automatic', [], 'message');
        $playerMoneyEditLog->save();

        $afterMoney = playerUpdateMoney($player, $playerMoneyEditLog, $data['type'], $money, 'wallet_modify', $playerMoneyEditLog->type == PlayerMoneyEditLog::TYPE_INCREASE ? PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_ADD : PlayerDeliveryRecord::TYPE_MODIFIED_AMOUNT_DEDUCT);

        $playerMoneyEditLog->origin_money = $originMoney;
        $playerMoneyEditLog->after_money = $afterMoney;
        $playerMoneyEditLog->save();
    }
}


if (!function_exists('playerUpdateMoney')) {
    /**
     * 玩家主錢包加扣點
     * @param Player $player 玩家信息
     * @param object $target 资料表
     * @param int $type 加点扣点
     * @param float $money 金额
     * @param string $source 来源
     * @param int $deliveryType 类型
     * @throws Exception
     */
    function playerUpdateMoney(Player $player, object $target, int $type, float $money, string $source, int $deliveryType)
    {
        if (!in_array($type, [PlayerMoneyEditLog::TYPE_DEDUCT, PlayerMoneyEditLog::TYPE_INCREASE])) {
            throw new Exception(admin_trans('player.wallet.wallet_type_error'));
        }

        if (!$player->id) {
            throw new Exception(admin_trans('player.wallet.player_error'));
        }

        if (!$target->id) {
            throw new Exception(admin_trans('player.wallet.wallet_action_log_not_found'));
        }

        //玩家加點數
        /** @var PlayerPlatformCash $machineWallet */
        $machineWallet = PlayerPlatformCash::where('platform_id', PlayerPlatformCash::PLATFORM_SELF)->where('player_id', $player->id)->first();
        $originMoney = $machineWallet->money;
        if ($type == PlayerMoneyEditLog::TYPE_INCREASE) {
            $machineWallet->money = bcadd($machineWallet->money, $money, 2);
        } else {
            if ($money > $originMoney) {
                throw new Exception(admin_trans('player.wallet.insufficient_player_money'));
            }
            $machineWallet->money = bcsub($machineWallet->money, $money, 2);
        }
        $machineWallet->save();
        //寫入金流明細
        $playerDeliveryRecord = new PlayerDeliveryRecord;
        $playerDeliveryRecord->player_id = $player->id;
        $playerDeliveryRecord->department_id = $player->department_id;
        $playerDeliveryRecord->target = $target->getTable();
        $playerDeliveryRecord->target_id = $target->id;
        $playerDeliveryRecord->type = $deliveryType;
        $playerDeliveryRecord->source = $source;
        $playerDeliveryRecord->amount = $money;
        $playerDeliveryRecord->amount_before = $originMoney;
        $playerDeliveryRecord->amount_after = $machineWallet->money;
        $playerDeliveryRecord->tradeno = $target->tradeno ?? '';
        $playerDeliveryRecord->remark = $target->remark ?? '';
        $playerDeliveryRecord->user_id = Admin::id() ?? 0;
        $playerDeliveryRecord->user_name = !empty(Admin::user()) ? Admin::user()->toArray()['username'] : trans('system_automatic', [], 'message');
        $playerDeliveryRecord->save();

        return $machineWallet->money;
    }
}

if (!function_exists('isTime')) {
    /**
     * 是否是时间格式
     * @param $timeStr
     * @return bool
     */
    function isTime($timeStr): bool
    {
        //年-月-日
        $regex1 = '/^\d{4}-\d{2}-\d{2}$/';
        //时:分:秒
        $regex2 = '/^\d{2}:\d{2}:\d{2}$/';
        //年-月-日 时:分:秒
        $regex3 = '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/';

        if (preg_match($regex1, $timeStr) || preg_match($regex2, $timeStr) || preg_match($regex3, $timeStr)) {
            return true;
        } else {
            return false;
        }
    }
}

if (!function_exists('getSeatOptions')) {
    /**
     * 炮台位置
     * @return array
     */
    function getSeatOptions(): array
    {
        return [
            1 => admin_trans('machine.seat.1'),
            2 => admin_trans('machine.seat.2'),
            3 => admin_trans('machine.seat.3'),
            4 => admin_trans('machine.seat.4'),
            5 => admin_trans('machine.seat.5'),
            6 => admin_trans('machine.seat.6'),
            7 => admin_trans('machine.seat.7'),
            8 => admin_trans('machine.seat.8'),
        ];
    }
}

if (!function_exists('getAdminUserListOptions')) {
    /**
     * 获取管理员列表
     * @param int $departmentId
     * @param int $type
     * @return array
     */
    function getAdminUserListOptions(int $departmentId = 1, int $type = 1): array
    {
        $optionList = [];
        $userList = AdminUser::query()->where('status', 1)->where('type', $type)->where('department_id', $departmentId)->whereNull('deleted_at')->get();
        /** @var AdminUser $item */
        foreach ($userList as $item) {
            $optionList[$item->id] = $item->nickname;
        }

        return $optionList;
    }
}

if (!function_exists('getDayOfWeek')) {

    /**
     * 数字转星期
     * @param $number
     * @return string
     */
    function getDayOfWeek($number): string
    {
        if ($number >= 0 && $number < 7) {
            return admin_trans('activity.week.' . $number);
        } else {
            return '';
        }
    }
}