<?php

namespace app\admin\controller;

use app\BaseController;
use app\admin\model\Recharge;
use app\admin\model\Withdraw;
use app\admin\model\Admin;
use app\admin\model\User;
use app\admin\model\FundsRecord;
use app\admin\model\DepositAddress;
use app\admin\validate\WalletValidate;
use Exception;
use think\facade\Db;

/**
 * 用户资金
 */
class Wallet extends BaseController
{

    /**
     * 充值通过
     * @apiParam {int} id 充值订单ID
     * @apiParam {String} safe_word 资金密码
     */
    function rechargePass()
    {
        $errors = [];
        Db::startTrans();
        try {
            $params = (new WalletValidate())->post()->goCheck('rechargePass');
            $admin = Admin::where('id', $this->admin_id)->find();
            if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
            $ro = Recharge::find($params['id']);
            if ($ro->status != 0) {
                $errors = ['id' => $ro->order_no];
                throw new Exception("该订单状态无法操作");
            }
            
            //获取汇率
            $currency_rate = getBlockChainFee($ro->currency);
            $ro->currency_rate = $currency_rate;//审核通过时候的汇率
            $ro->actual_received = bcmul($ro->recharge_amount, $currency_rate, 2);//实际到账的usdt
            $ro->status = 1;
            $ro->operation_time = time();
            $ro->save();

            $user = User::where('user_id', $ro->user_id)->find();
            $userMoney = bcadd($user->money, $ro->actual_received, 2);
            FundsRecord::addData([
                'transaction_type' => 'recharge',
                'amount_change' => $ro->actual_received,
                'balance_before' => $user->money,
                'balance_after' => $userMoney,
                'user_id' => $user->user_id
            ]);
            
            $user->money = $userMoney;
            $user->save();
            DB::commit();
        } catch (Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage(), $errors);
        }
        return $this->success();
    }

    /**
     * 充值驳回
     * @apiParam {int} id 充值订单ID
     * @apiParam {String{0..200}} operation_remark 驳回原因
     *
     */
    function rechargeRefuse()
    {
        $errors = [];
        Db::startTrans();
        try {
            $params = (new WalletValidate())->post()->goCheck('rechargeRefuse');
            $operationRemark = $params['operation_remark'] ?? '';
            $ro = Recharge::findOrFail($params['id']);
            if ($ro->status != 0) {
                $errors = ['id' => $ro->order_no];
                throw new Exception("该订单状态无法操作");
            }
            $ro->status = 2;
            $ro->operation_remark = $operationRemark;
            $ro->operation_time = time();
            $ro->save();
            Db::commit();
        } catch (Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage(), $errors);
        }
        return $this->success();

    }

    /**
     * 充值订单
     */
    function recharges()
    {
        try {
            $params = $this->request->param();
   
            $page = isset($params['page']) ? intval($params['page']) : 1;
            $limit = isset($params['limit']) ? intval($params['limit']) : 15;
            
            $query = Recharge::alias('recharge')
                        ->join(env('database.DATABASE').'.bot_users user', 'recharge.user_id = user.user_id', 'left');
                        // ->join('user', 'recharge.user_id=user.user_id','left');
           
            if (isset($params['start_time'])) {
                $start_time = strtotime($params['start_time'].' 00:00:00');
                $query = $query->where('recharge.create_time', '>=', $start_time);
            }
            if (isset($params['end_time'])) {
                $end_time = strtotime($params['end_time'].' 23:59:59');
                $query = $query->where('recharge.create_time', '<=', $end_time);
            }
            if (isset($params['operation_start'])) {
                $operation_start = strtotime($params['operation_start'].' 00:00:00');
                $query->where('recharge.operation_time', '>=', $operation_start);
            }
            if (isset($params['operation_end'])) {
                $operation_end = strtotime($params['operation_end'].' 23:59:59');
                $query->where('recharge.operation_time', '<=', $operation_end);
            }
            if (isset($params['status']) && $params['status'] !== null) {
                $query->where('recharge.status', $params['status']);
            }
            if (!empty($params['order_no'])) {
                $query->where('recharge.order_no', $params['order_no']);
            }
            if (!empty($params['currency'])) {
                $query->where('recharge.currency', $params['currency']);
            }
            if (!empty($params['realname'])) {
                $query = $query->where(function ($query) use ($params) {
                    $query->where('user.realname', 'like', "%{$params['realname']}%")
                        ->orWhere('user.user_id', 'like', "%{$params['realname']}%");
                });
            }

            $count = $query->count();
            $list = $query->field(['recharge.*','user.realname', 'user.user_id', 'user.remark','user.phone','user.email'])
                ->limit($limit)
                ->page($page)
                ->order('recharge.create_time','desc')
                ->select()->toArray();

        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success(['count' => $count, 'list' => $list]);

    }

    /**
     * 提现驳回
     */
    function withdrawRefuse()
    {
        $errors = [];
        Db::startTrans();
        try {
            $params = (new WalletValidate())->post()->goCheck('withdrawRefuse');
            $operationRemark = $params['operation_remark'] ?? '';
            $wo = Withdraw::findOrFail($params['id']);
            if ($wo->status != 0) {
                $errors = ['id' => $wo->order_no];
                throw new Exception("该订单状态无法操作");
            }
            $user = User::where('user_id', $wo->user_id)->find();
            $userMoney = bcadd($user->money, $wo->deduction_usd, 2);
            FundsRecord::addData([
                'transaction_type' => 'withdraw',
                'amount_change' => $wo->deduction_usd,
                'balance_before' => $user->money,
                'balance_after' => $userMoney,
                'user_id' => $user->user_id
            ]);
            $wo->status = 2;
            $wo->operation_remark = $operationRemark;
            $wo->operator_id = $this->admin_id;
            $wo->operation_time = time();
            $wo->save();
            $user->money = $userMoney;
            $user->save();
            Db::commit();
        } catch (Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage(), $errors);
        }
        return $this->success();

    }

    /**
     * @api {post} /wallet/withdrawPass 提现通过
     * @apiDescription 需要手动打款后来此操作
     * @apigroup 财务
     * @apiVersion 1.0.0
     * @apiUse header
     * @apiUse lang
     *
     * @apiParam {int} id 提现订单的ID
     * @apiParam {String} safe_word 资金密码
     */
    function withdrawPass()
    {
        $errors = [];
        Db::startTrans();
        try {
            $params = (new WalletValidate())->post()->goCheck('withdrawPass');
            $safeWord = $params['safe_word'] ?? '';
            $admin = Admin::where('id', $this->admin_id)->find();
            if (!password_verify($safeWord, $admin->payment_password)) throw new Exception('资金密码错误');
            $wo = Withdraw::findOrFail($params['id']);
            if ($wo->status != 0) {
                $errors = ['id' => $wo->order_no];
                throw new Exception("该订单状态无法操作");
            }
            $wo->operation_time = date('Y-m-d H:i:s');
            $wo->operator_id = $this->admin_id;
            $wo->status = 1;
            $wo->save();
            Db::commit();
        } catch (Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage(), $errors);
        }
        return $this->success();
    }

    /**
     *  提现收款地址修改
     */
    function updateAddress()
    {
        $errors = [];
        Db::startTrans();
        try {
            $params = (new WalletValidate())->post()->goCheck('updateAddress');
            $admin = Admin::where('id', $this->admin_id)->find();
            if (!password_verify($params['safe_word'], $admin->payment_password)) throw new Exception('资金密码错误');
            $wo = Withdraw::find($params['id']);
            if ($wo->status != 0) {
                $errors = ['id' => $wo->order_no];
                throw new Exception("该订单状态无法操作");
            }
            if ($wo->currency == 'bank') {
                $wo->bank_card_no = $params['address'];
            } else {
                $wo->channel_address = $params['address'];
            }
            $wo->save();

            Db::commit();
        } catch (Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage(), $errors);
        }
        return $this->success();
    }

    /**
     *  订单类型
     */
    public function rechargeAddress()
    {
        $list = DepositAddress::field(['currency', 'network_type', 'address', 'withdraw_fee','is_withdraw'])->select()->toArray();
        $list[] = [
            'currency' => '银行卡',
            'network_type' => 'BANK',
            'address' => '',
            'withdraw_fee' => '0.00',
            'is_withdraw'   => 0,
        ];
        return $this->success($list);
    }

    /**
     * 提现订单
     */
    public function withdraws()
    {
        try {
            $params = $this->request->param();
            $page = isset($params['page']) ? intval($params['page']) : 1;
            $limit = isset($params['limit']) ? intval($params['limit']) : 15;
            $query = Withdraw::alias('withdraw')
                        ->join(env('database.DATABASE').'.bot_users user', 'withdraw.user_id = user.user_id', 'left');
                        // ->join('user', 'withdraw.user_id=user.user_id','left');
           
            if (isset($params['start_time'])) {
                $start_time = strtotime($params['start_time'].' 00:00:00');
                $query = $query->where('withdraw.create_time', '>=', $start_time);
            }
            if (isset($params['end_time'])) {
                $end_time = strtotime($params['end_time'].' 23:59:59');
                $query = $query->where('withdraw.create_time', '<=', $end_time);
            }
            if (isset($params['operation_start'])) {
                $operation_start = strtotime($params['operation_start'].' 00:00:00');
                $query->where('withdraw.operation_time', '>=', $operation_start);
            }
            if (isset($params['operation_end'])) {
                $operation_end = strtotime($params['operation_end'].' 23:59:59');
                $query->where('withdraw.operation_time', '<=', $operation_end);
            }
            if (isset($params['status']) && $params['status'] !== null) {
                $query->where('withdraw.status', $params['status']);
            }
            if (!empty($params['order_no'])) {
                $query->where('withdraw.order_no', $params['order_no']);
            }
            if (!empty($params['currency'])) {
                $query->where('withdraw.currency', $params['currency']);
            }
            if (!empty($params['realname'])) {
                $query = $query->where(function ($query) use ($params) {
                    $query->where('user.realname', 'like', "%{$params['realname']}%")
                        ->orWhere('user.user_id', 'like', "%{$params['realname']}%");
                });
            }
            if (!empty($params['method'])) {
                if ($params['method'] == '银行卡') $params['method'] = 'bank';
                $query->where('withdraw.currency', $params['method']);
            }
            $count = $query->count();
            $list = $query->field(['withdraw.*','user.realname', 'user.user_id', 'user.remark','user.phone','user.email'])
                ->order('withdraw.create_time','desc')
                ->limit($limit)
                ->page($page)
                ->select();

        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success(['count' => $count, 'list' => $list]);
    }

    /**
     *  更改用户余额
     */
    public function changeMoney()
    {
        Db::startTrans();
        try {
            $params = $this->request->param();
            $admin = request()->user;
            if (!password_verify($params['payment_password'], $admin->payment_password)) {
                throw new Exception('资金密码错误');
            }

            $amount = $params['amount'];
            $user = User::where('user_id', $params['user_id'])->find();
            switch ($params['type']) {
                case "withdraw":
                    if ($user->money < $amount) {
                        throw new Exception("余额不足");
                    }
                    $balance_after = bcsub($user->money, $amount, 2);
                    FundsRecord::addData([
                        'transaction_type' => 'withdraw',
                        'amount_change' => $amount * -1,
                        'balance_before' => $user->money,
                        'balance_after' => $balance_after,
                        'user_id' => $user->user_id
                    ]);

                    Withdraw::addData([
                        'user_id' => $user->user_id,
                        'currency' => 'USDT',
                        'network_type' => 'TRC20',
                        'channel_address' => '',
                        'amount' => $amount,
                        'status' => 1,
                        'remarks' => '',
                        'actual_received' => $amount,
                        'operation_time' => time(),
                        'handling_fee' => 0,
                        'deduction_usd' => $amount,
                    ]);
                    $user->money = $balance_after;
                    $user->save();
                    break;
                case 'recharge':
                    $balance_after = bcadd($user->money, $amount, 2);
                    FundsRecord::addData([
                        'transaction_type' => 'recharge',
                        'amount_change' => $amount,
                        'balance_before' => $user->money,
                        'balance_after' => $balance_after,
                        'user_id' => $user->user_id
                    ]);
                    Recharge::addData([
                        'currency' => 'USDT',
                        'network_type' => 'TRC20',
                        'user_id' => $user->user_id,
                        'recharge_amount' => $amount,
                        'actual_received' => $amount,
                        'payment_receipt' => '',
                        'status' => 1,
                        'operation_time' => time(),
                    ]);

                    $user->money = $balance_after;
                    $user->save();
                    break;
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();

    }

    /**
     *  用户资金记录
     */
    public function fundsRecords()
    {
        try {
            $params = $this->request->param();
            $data = FundsRecord::getList($params, '');
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success($data);
    }

}