<?php
/**
 * Created by PhpStorm.
 * User: pengfei@yidian-inc.com
 * Date: 2021/9/3 2:23 下午
 */

use App\Base\Job;
use App\Models\marketing\mysql\ColonelDistributorPayInfo;
use Api\PhpUtils\Http\HttpUtil;
use Api\PhpUtils\Log\JobLog;
use App\Services\marketing\ColonelService;

class ColonelwalletController extends Job
{
    const CAPITAL_POOL_OP = 200; //200：团长奖励
    const WALLET_SERVICE_NAME = 10; // 10生活圈优惠券，11营销活动
    const WALLET_SOURCE_NAME = 1; //使用方名，1生活圈，2主端
    const WALLET_ORDER_TYPE_USER  = 601; // 钱包-邀请新用户奖励类型
    const WALLET_ORDER_TYPE_ORDER = 602; // 钱包-邀请下单奖励类型

    public $capitalPoolId = null;

    /**
     * Notes: 初始化-读取配置
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/10 10:01 上午
     */
    public function init()
    {
        parent::init();
        $marketing = ColonelService::getMarketingInfo();
        $this->capitalPoolId = $marketing['capital_pool_id'] ?? 0;
    }

    /**
     * Notes: 奖励结算脚本
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/9 11:17 上午
     */
    public function indexAction()
    {
        $this->loggerInfo('start');
        $payInfoList = $this->getPayInfoList();
        $this->loggerInfo('payInfoCount=' . count($payInfoList));
        if (!empty($payInfoList)) {
            try {
                if ($this->deductingInventory($payInfoList)) {
                    if ($this->toWallet($payInfoList)) {
                        $this->handlePayInfoStatus(array_column($payInfoList, 'pay_info_id'));
                    }
                }
                $this->loggerInfo('success');
            } catch (Exception $e) {
                $this->loggerError('error:' . $e->getMessage());
            }
        }
        $this->loggerInfo('end');
    }

    /**
     * Notes: 结算写入钱包
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 6:04 下午
     * @param $payInfoList
     * @return bool
     * @throws Exception
     */
    private function toWallet($payInfoList): bool
    {
        if (!$url = config('interface', 'wallet.account.transfer')) {
            throw new Exception('没有wallet.account.transfer配置');
        }
        $httpParams = self::getWalletHttpParams();
        $list = [];
        foreach ($payInfoList as $payInfo) {
            $thirdOrderInfo = self::getThirdOrderInfo($payInfo);
            $list[] = [
                'user_id'             => $payInfo['colonel_user_id'],
                'service_name'        => self::WALLET_SERVICE_NAME,
                'source_name'         => self::WALLET_SOURCE_NAME,
                'third_order_id'      => $payInfo['pay_info_trade_id'],
                'third_order_id_type' => $thirdOrderInfo['type'],
                'third_order_desc'    => $thirdOrderInfo['desc'],
                'amount'              => $payInfo['reward'],
                'extra'               => ''
            ];
        }
        $httpParams['list'] = $list;
        $response = HttpUtil::post($url, $httpParams, 100000, 3);
        $this->loggerInfo("url=$url,response:" . json_encode($response));
        if (!empty($response['response']['result']) && $response['code'] == 0) {
            $this->loggerInfo('调用钱包服务成功,count=' . count($payInfoList));
            return true;
        } else {
            throw new Exception('调用钱包服务失败,' . json_encode(['req' => $httpParams, 'res' => $response]));
        }
    }


    /**
     * Notes: 资金池授予用户奖励
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 6:04 下午
     * @param $payInfoList
     * @return bool
     * @throws Exception
     */
    private function deductingInventory($payInfoList): bool
    {
        if (!$url = config('interface', 'coupon.capitalpool.grant_user_amount')) {
            throw new Exception('没有grant_user_amount配置');
        }
        $httpParams = [
            'capital_pool_id' => $this->capitalPoolId
        ];
        $body = [];
        foreach ($payInfoList as $payInfo) {
            $thirdOrderInfo = self::getThirdOrderInfo($payInfo);
            $body[] = [
                'op'                  => self::CAPITAL_POOL_OP,
                'user_id'             => $payInfo['colonel_user_id'],
                'amount'              => $payInfo['reward'],
                'third_order_id'      => $payInfo['pay_info_trade_id'],
                'third_order_id_type' => $thirdOrderInfo['type'],
                'third_order_desc'    => $thirdOrderInfo['desc'],
            ];
        }
        $httpParams['body'] = $body;
        $res = HttpUtil::post($url, $httpParams, 100000, 3);
        $this->loggerInfo("url=$url,response:" . json_encode($res));
        if ($res['code'] == 0 && isset($res['response']['result'])) {
            $this->loggerInfo('调用资金池服务成功,count=' . count($payInfoList));
            return true;
        } else {
            throw new Exception('调用资金池服务失败,' . ['req' => $httpParams,'res' => $res]);
        }
    }

    /**
     * Notes: 获取钱包服务请求参数
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 7:34 下午
     * @return array
     */
    private function getWalletHttpParams(): array
    {
        // TODO 此处看后期业务发展 看是否需要封装WalletSdk
        $date = date('Y-m-d H:i:s');
        return [
            'transfer_service_id' => appConfig('colonel.wallet.transfer_service_id'),
            'sign'                => self::getWalletHttpSign($date),
            'time'                => $date
        ];
    }

    /**
     * Notes: 获取钱包签名
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 7:34 下午
     * @param $date
     * @return string
     */
    private function getWalletHttpSign($date): string
    {
        return md5($date . appConfig('colonel.wallet.transfer_service_secret'));
    }

    /**
     * Notes: 获取待结算数据
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 7:23 下午
     * @return array
     */
    private function getPayInfoList(): array
    {
        return ColonelDistributorPayInfo::getRecords(['status' => ColonelDistributorPayInfo::STATUS_NOT_USE]);
    }

    /**
     * Notes: 获取描述信息
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 6:10 下午
     * @param $payInfo
     * @return array
     */
    private function getThirdOrderInfo($payInfo): array
    {
        $info = [];
        if ($payInfo['type'] == ColonelDistributorPayInfo::TYPE_NEW_USER) {
            $info = [
                'desc' => "邀请新用户（" . $payInfo["invite_user_nick"] . "）完成下单奖励",
                'type' => self::WALLET_ORDER_TYPE_USER,
            ];
        } elseif ($payInfo['type'] == ColonelDistributorPayInfo::TYPE_FINISH_TARGET) {
            $info = [
                'desc' => "完成" . $payInfo["finish_num"] . "单用户下单奖励",
                'type' => self::WALLET_ORDER_TYPE_ORDER,
            ];
        }
        return $info;
    }


    /**
     * Notes: 修改状态
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/9 11:15 上午
     * @param array $payInfoIds
     * @return bool
     * @throws Exception
     */
    private function handlePayInfoStatus(array $payInfoIds): bool
    {
        $upStatus = ColonelDistributorPayInfo::updateRecord(
            ['status' => ColonelDistributorPayInfo::STATUS_USE],
            ['pay_info_id' => $payInfoIds]
        );
        if (empty($upStatus)) {
            throw new Exception('更新pay_info状态失败.pay_info_ids=' . implode(',', $payInfoIds));
        }
        return $upStatus;
    }

    /**
     * Notes: 记录 info 日志
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 4:10 下午
     * @param $log
     */
    private function loggerInfo($log)
    {
        JobLog::getInstance()->info('colonel_distributor_wallet', $log, false)->output();
    }

    /**
     * Notes: 记录 error 日志
     * User: pengfei@yidian-inc.com
     * Date: 2021/9/3 4:10 下午
     * @param $log
     */
    private function loggerError($log)
    {
        JobLog::getInstance()->error('colonel_distributor_wallet', $log, null, 'bp-server@yidian-inc.com')->output();
    }
}
