<?php

namespace app\api\controller\user;

use app\models\user\UserBill;
use app\models\user\UserExtract;
use app\Request;
use tw\services\payment\MachantPay;
use tw\services\controller\PaymentService;
use crmeb\services\UtilService;
use tw\redis\UserRds;

/**
 * 提现类
 * Class UserExtractController
 * @package app\api\controller\user
 */
class UserExtractController
{
    /**
     * @api {get} /extract/bank 提现银行
     * @apiName ExtractBank
     * @apiGroup User.Extract
     * 
     * @apiDescription 提现前请求，用户显示和客户端过滤
     * 
     * @apiSuccess {float} broken_commission 冻结佣金
     * @apiSuccess {float} brokerage_price 总佣金
     * @apiSuccess {float} commissionCount  可提现佣金
     * @apiSuccess {string[]} extractBank   可体现银行列表
     * @apiSuccess {float} minPrice 最小提现金额
     * @apiSuccess {string} wxpayName 微信实名(以下 4 个参数用于记忆功能)
     * @apiSuccess {string} bankCardNo 银行卡号
     * @apiSuccess {string} bankUser 银行户名
     * @apiSuccess {string} bankName 银行名
     */
    public function bank(Request $request)
    {
        $user = $request->user();
        // 佣金冻结时间
        $frozen_days = intval(sys_config('extract_time'));
        $frozen_from = time() - 86400 * $frozen_days;
        //可提现佣金
        $brokerage_commission = UserBill::where(['uid' => $user['uid'], 'category' => 'now_money', 'type' => 'brokerage'])
            ->where('add_time', '>', $frozen_from)
            ->where('pm', 1)
            ->sum('number');
        $refund_commission = UserBill::where(['uid' => $user['uid'], 'category' => 'now_money', 'type' => 'brokerage'])
            ->where('add_time', '>', $frozen_from)
            ->where('pm', 0)
            ->sum('number');
        $data['broken_commission'] = floatval(bcsub($brokerage_commission, $refund_commission, 2));
        if ($data['broken_commission'] < 0) {
            $data['broken_commission'] = 0;
        }

        $data['brokerage_price'] = $user['brokerage_price'];
        //可提现佣金
        $data['commissionCount'] = floatval(bcsub($data['brokerage_price'], $data['broken_commission'], 2));
        $extractBank = sys_config('user_extract_bank') ?? []; //提现银行
        $extractBank = str_replace("\r\n", "\n", $extractBank); //防止不兼容
        $data['extractBank'] = explode("\n", is_array($extractBank) ? (isset($extractBank[0]) ? $extractBank[0] : $extractBank) : $extractBank);
        $data['minPrice'] = sys_config('user_extract_min_price'); //提现最低金额
        // 输入记忆
        $cach = (new UserRds)->gets($user['uid'], [
            UserRds::FILED_WXPAYNAME,
            UserRds::FIELD_BANKCARDNO,
            UserRds::FIELD_BANKUSER,
            UserRds::FIELD_BANKNAME,
        ]);
        $data['wxpayName']  = $cach[UserRds::FILED_WXPAYNAME] ? $cach[UserRds::FILED_WXPAYNAME] : '';
        $data['bankCardNo'] = $cach[UserRds::FIELD_BANKCARDNO] ? $cach[UserRds::FIELD_BANKCARDNO] : '';
        $data['bankUser']   = $cach[UserRds::FIELD_BANKUSER] ? $cach[UserRds::FIELD_BANKUSER] : '';
        $data['bankName']   = $cach[UserRds::FIELD_BANKNAME] ? $cach[UserRds::FIELD_BANKNAME] : '';

        return app('json')->successful($data);
    }

    /**
     * @api {post} /extract/bank_fee 查询银行提现手续费
     * @apiName PostExtractBankFee
     * @apiGroup User.Extract
     * 
     * @apiBody {int} extract_type 提现类型/通道
     * @apiBody {float} money 提现金额
     * 
     * @apiDescription 用于提示
     * 
     * @apiSuccess {float} rate 手续费率
     * @apiSuccess {float} min 最少收取
     * @apiSuccess {float} max 最多收取
     * @apiSuccess {float} fee 当前收取
     * @apiSuccess {float} valid 实际到帐金额
     */
    public function bank_fee(Request $request)
    {
        $extractInfo = UtilService::postMore([
            ['alipay_code', ''],
            ['extract_type', ''],
            ['money', 0],
            ['name', ''],
            ['bankname', ''],
            ['cardnum', ''],
            ['weixin', ''],
        ], $request);
        $user = $request->user();


        if ($extractInfo['extract_type'] != 'bank') {
            return app('json')->fail('不是银行卡提现');
        }
        if ($extractInfo['money'] < sys_config('user_extract_min_price')) {
            return app('json')->fail('金额小于最低提现金额');
        }

        $bankMax = 1000; // 银行渠道限额
        if ($extractInfo['money'] > $bankMax) {
            return app('json')->fail("金额不能超过 $bankMax 元");
        }

        list($ok, $fee, $rate, $min, $max) = MachantPay::toBankByWeixinFee($extractInfo['money']);
        if (!$ok) {
            return app('json')->fail('金额错误');
        }

        // 实际到帐金额
        $valid = floatval(bcsub($extractInfo['money'], $fee, 2));

        return app('json')->successful([
            'rate' => $rate,       // 费率
            'min' => $min,         // 最少收费
            'max' => $max,         // 最大收费
            'fee' => $fee,         // 当前收费
            'valid' => $valid,      // 实际到帐
        ]);
    }
    /**
     * @deprecated
     */
    public function cash(Request $request)
    {
        $extractInfo = UtilService::postMore([
            ['alipay_code', ''],
            ['extract_type', ''],
            ['money', 0],
            ['name', ''],
            ['bankname', ''],
            ['cardnum', ''],
            ['weixin', ''],
        ], $request);
        $user = $request->user();

        list($suc, $msg) = PaymentService::user_request_extract($user, $extractInfo);
        if ($suc) {
            return app('json')->successful('申请提现成功!');
        } else {
            return app('json')->fail($msg);
        }
    }

    /**
     * 即时提現，參數返回值同 cash
     * 本接口支持即時到帐，调用三方支付提现 API
     * 
     * 用户账户必须满足以下规则。
     * 1. 满足对应提现通道要求，微信支付：每个用户1天限1次，每次限200, 平台每日限额 200,000
     * 2. 15 日内必须有退款订单。且30日内退款订单金额 > 提现金额
     * 3. 其他基本需求(最低提现限额等等)
     * 
     * 不满足体现条件，则交给人工处理
     * API 执行失败，则必须重新提交提现请求，因为人工操作也是失败。
     * 如果API 返回 SYSTEMERROR, 则按照原订单参数重新提交。
     */

    /**
     * @api {post} /extract/cash 提现申请
     * @apiName ExtractCash
     * @apiGroup User.Extract
     * 
     * @apiBody {string} alipay_code 支付宝号码
     * @apiBody {string="alipay","bank","weixin"} extract_type 提现类型
     * @apiBody {float} money 提现金额
     * @apiBody {string} bankName 开户行
     * @apiBody {string} cardnum 卡号
     * @apiBody {string} name 微信实名/银行户名/支付宝帐号
     * @apiBody {string} weixin 微信实名
     * 
     * @apiSuccessExample Succeed
     * {
     * 
     * }
     * @apiErrorExample Failed
     * {
     *  
     * }
     * 
     */
    public function flash_cash(Request $request)
    {
        // 提交申请
        $extractInfo = UtilService::postMore([
            ['alipay_code', ''],
            ['extract_type', ''],
            ['money', 0],
            ['name', ''],
            ['bankname', ''],
            ['cardnum', ''],
            ['weixin', ''],
        ], $request);
        $user = $request->user();

        list($suc, $msg) = PaymentService::user_request_extract($user, $extractInfo);
        if (!$suc) {
            return app('json')->fail($msg);
        }
        $row = $msg;
        $extractRow = UserExtract::getUserExtractInfo($user['uid'], $row['extract_type'], $row['add_time']);
        if (!$extractRow) {
            errlog('Unbelievable error getUserExtractInfo(' . $user['uid'] . ' ' . $row['add_time'] . ')');
            return app('json')->fail('提交申请失败');
        }
        // 检查条件
        list($suc, $msg) = PaymentService::user_extract_auto_conditions($user);
        if (!$suc) {
            // 条件不满足，不进一步处理，相当与交给人工处理
            return app('json')->fail($msg);
        }

        // API
        list($suc, $ec, $es) = PaymentService::extract_by_api($extractRow);

        if (!$suc) {
            // API 失败 直接拒绝，因为重试也会大概率失败
            list($ok, $msg) = PaymentService::user_extract_reject($extractRow['id'], $es);
            if (!$ok) {
                errlog('user_extract_reject()' . $extractRow['id']);
            }
            return app('json')->fail($es);
        } else {
            list($ok, $msg) = PaymentService::user_extract_passed($extractRow);
            if (!$ok) {
                errlog('user_extract_passed()' . $extractRow['id']);
            }
            return app('json')->successful('提现成功');
        }
    }
}
