<?php

namespace app\controller\api\store\product;

use app\common\repositories\store\product\ProductRepository;
use app\common\repositories\user\UserThirdRepository;
use app\model\common\UserThirdModel;
use function GuzzleHttp\Promise\exception_for;
use function GuzzleHttp\Psr7\build_query;
use think\App;
use crmeb\basic\BaseController;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Db;

class TaoBao extends BaseController
{

    public $appKey = '';
    public $secretKey = '';
    public $adzone_id = '';
    public $adzone = '';
    public $wuliao = '';
    public $userThird;
    public $url;

    public function __construct(App $app)
    {

        parent::__construct($app);
        $this->appKey = '31940963';
        $this->secretKey = 'f8437ad5821d697bae35f3fa613b6370';
        //淘宝客pid
        $this->adzone = "mm_1411990095_2149000369_111007900247";//默认
        //推广位id，mm_xx_xx_xx pid三段式中的第三段
        $this->adzone_id = '111007900247';
        $this->wuliao = '2836'; //默认特惠商品
        $this->userThird = app()->make(UserThirdRepository::class);
        $this->url = 'https://router.jd.com/api';
    }

    /**
     * 生成签名
     */
    function createSign($paramArr)
    {
        $sign = $this->secretKey;
        ksort($paramArr);
        foreach ($paramArr as $key => $val) {
            if ($key != '' && $val != '') {
                $sign .= $key . $val;
            }
        }
        $sign .= $this->secretKey;
        $sign = strtoupper(md5($sign));
        return $sign;
    }


    /*curl*/
    public function do_execute($url, $apiParams, $sign_conf)
    {
        $timestamp = date("Y-m-d H:i:s");
        $apiParams ['timestamp'] = $timestamp;
        $sign_conf['timestamp'] = $timestamp;
        $apiParams ['sign'] = $this->createSign($sign_conf); // 签名生成sign

        // 如果参数为数组则
        if (is_array($apiParams) && 0 < count($apiParams)) {
            $postBodyString = "";
            foreach ($apiParams as $k => $v) {
                $postBodyString .= "$k=" . urlencode($v) . "&";
            }
            unset ($k, $v);
        } else {
            $postBodyString = $apiParams;
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        try {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));
            $reponse = curl_exec($ch);
            if (curl_errno($ch)) {
                $curl_error = curl_error($ch);
                throw new Exception ($curl_error, 0);
            } else {
                $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                if (200 !== $httpStatusCode) {
                    throw new Exception ($reponse, $httpStatusCode);
                }
            }
        } catch (Exception $e) {
        }
        curl_close($ch);
        return $reponse;
    }

    /*公共参数*/
    public function paramOrder($param, $isHttps = false)
    {
        $para = array(
            'format' => 'json',
            'v' => '2.0',
            'sign_method' => 'md5',
            'app_key' => $this->appKey,
            'app_secret' => $this->secretKey,
        );
        $para = array_merge($para, $param);
        if ($isHttps) {
            $url = 'https://eco.taobao.com/router/rest';
        } else {
            $url = 'http://gw.api.taobao.com/router/rest';
        }
        $result = $this->do_execute($url, $para, $para);
        $arr = json_decode($result, true);
        return $arr;
    }


    /*列表*/
    public function goodList()
    {
        $data = $data = $this->request->params([
            'material_id',
            'title',
            'cat'
        ]);
        [$page, $limit] = $this->getPage();
        if (!$data['cat']) {
            $catarr = $this->userThird->getMaterial();
            foreach ($catarr as $cat) {
                $data['cat'] .= $cat['material_id'];
            }
        }
        $param = [
            'method' => 'taobao.tbk.dg.material.optional', //  taobao.tbk.dg.optimus.material
//            'material_id' => $data['material_id'] ? $data['material_id'] : $this->wuliao,//物料id
            'adzone_id' => $this->adzone_id,
            'page_no' => $page,
            'page_size' => 20,
            'platform' => 2
        ];
        if ($data['cat']) {
            $param['cat'] = $data['cat'];
        }
        if ($data['title']) {
            $param['q'] = $data['title'];
        }
        //var_dump($param);
        $result = $this->paramOrder($param);
        $result = $result['tbk_dg_material_optional_response']['result_list']['map_data'];
        //var_dump($result);
        if (!$result) {
            return app('json')->success('未查询到商品', []);
        }
        $goodsList = [];
        foreach ($result as $goods) {
            $goodsList[] = [
                'type' => 5,//淘宝商品
                'id' => $goods['item_id'], //商品id
                'thumb' => $goods['pict_url'],//商品缩略图
                'name' => $goods['title'], //名称
                'commission' => app()->make(ProductRepository::class)->yanglaojin(0, $goods['zk_final_price'] * ($goods['commission_rate'] / 100) / 100),//佣金
                'commission_rate' => $goods['commission_rate'] / 100, //佣金比例
                'sales' => $goods['volume'], //销量
                'coupon_money' => $goods['coupon_amount'] ?? 0, //优惠券金额
                'market_price' => $goods['zk_final_price'], //折扣价
                'price' => $goods['reserve_price'], //原价
                'coupon_share_url' => $goods['coupon_share_url'] ?? ''
            ];
        }

        return app("json")->success($goodsList);

    }

    //通过大淘客获取商品列表
    public function dataokeGoodsList()
    {
        try {


            $cids = request()->param('cat', 0);
            $keyword = request()->param('title', '');
            [$page, $pageSize] = $this->getPage();
            if ($keyword != '') {
                $uid = $this->request->uid();
                TaoKe::set_third_history($uid, $keyword);
            }

            $result = DaTaoKe::goodsList($page, $pageSize, $cids, $keyword);
            if ($result['code'] == 0) {
                return app("json")->fail($result['msg'], $result['data']);
            } else {
                return app("json")->success($result['msg'], $result['data']);
            }
        }catch (\Exception $exception){
            Db::name('log')->insert(['data'=>'淘宝商品列表出错：'.$exception->getFile().'：'.$exception->getLine().'【'.$exception->getMessage().'】']);
        }
    }

    /*商品详情*/
    public function goodsDetail($id)
    {
        $uid = $this->request->uid();
        $param = [
            'method' => 'taobao.tbk.item.info.get',
            'num_iids' => $id,//商品id
            'platform' => 2
        ];
        $result = $this->paramOrder($param);
        $result = $result['tbk_item_info_get_response']['results']['n_tbk_item'][0];
//        $link = $this->changeLink($uid, $id);
        $link = DaTaoKe::changeLink($id, $uid);
        if ($link['code'] == 1) {
            $result['link'] = $link;
            $result['item_url'] = $link['link'];
        }
        return app("json")->success($result);
    }


    //淘宝客商品领券购买方法
    public function getCpsLink($id)
    {
        $goodsId = $id;
        $userId = $this->request->uid();
        $thirdInfo = $this->userThird->getDetail(['uid' => $userId, 'type' => 5]);
        //如果没有绑定relation_id需要获取授权绑定relation_id
        if (empty($thirdInfo)) {
            $state = "{$userId}_{$goodsId}";
            $link = $this->getAuthUrl($state);
        } else {
            $result = DaTaoKe::changeLink($goodsId, $userId);
            if ($result['code'] == 0) {
                return \app('json')->fail('获取转链地址出错', $result['raw']);
            }
            $link = $result['link'];
        }
        return \app('json')->success('ok', ['link' => $link]);
    }



    /**
     * 大淘客转链功能
     * @param $goodsId
     * @param $userId
     * @return mixed|string
     * @author daoheng
     */
    public function dataokeChangeLink($goodsId, $userId)
    {
        try {
            $relationId = '';
            if ($userId) {
                $where = ['uid' => $userId, 'type' => 5];
                $thirdInfo = UserThirdModel::getInstance()->getOne($where);
                $relationId = $thirdInfo['pid'];
            }
            $changUrl = 'https://openapi.dataoke.com/api/tb-service/get-privilege-link';
            $queryData = [
                'appKey' => DaTaoKe::$appKey,
                'version' => 'v1.3.1',
                'goodsId' => $goodsId,
                'pid' => DaTaoKe::$pid,
            ];
            if ($relationId) {//渠道id
                $queryData['channelId'] = $relationId;
            }
            $appSecret = DaTaoKe::$appSecret;
            //生成大淘客签名
            $queryData['sign'] = DaTaoKe::makeSign($queryData, $appSecret);
            $url = "{$changUrl}?" . http_build_query($queryData);
            $response = DaTaoKe::sendCurl($url);
            return $response['code'] != 0 ? '' : $response['data']['shortUrl'];
        } catch (\Throwable $throwable) {
            return $throwable->getMessage();
        }
    }


    /*带会员id转链*/
    public function changeLink($uid, $id)
    {
        $pid = $this->userThird->getDetail(['uid' => $uid, 'type' => 5]);
        $param = [
            'method' => 'taobao.tbk.item.convert',
            'fields' => 'num_iid,click_url',//需返回的字段列表
            'num_iids' => $id,//商品id
            'adzone_id' => $pid['pid'],
            'platform' => 2
        ];
        $result = $this->paramOrder($param);
        //var_dump($result);
        $result = $result['tbk_item_convert_response']['results']['n_tbk_item']['click_url'] ?? '';
        return $result;
    }

    //返回商品的转链(官方转链,没有权限)
    public function goodsChangeLink($goodsId, $userId = '')
    {
        $relationId = '';
        if ($userId) {
            $thirdInfo = $this->userThird->getDetail(['uid' => $userId, 'type' => 5]);
            $relationId = $thirdInfo['pid'];
        }
        $param = [
            'method' => 'taobao.tbk.item.convert',
            'fields' => 'num_iid,click_url',//需返回的字段列表
            'num_iids' => $goodsId,//商品id
            'adzone_id' => $this->adzone_id,
            'platform' => 2,
            'uuid' => 'daoheng11',
        ];
        $result = $this->paramOrder($param);
        $response = $result['tbk_item_convert_response']['results']['n_tbk_item'];
        $result = reset($response);
        $linkRaw = $result['click_url'];
        if ($relationId) {
            $linkRaw .= "?relationId={$relationId}";
        }
        return $linkRaw;
    }

    //淘宝客测试方法
    public function test()
    {
        $result = DaTaoKe::changeLink(631306545169, 10);
        return \app('json')->success('ok', $result);
        $param = [
            'method' => 'taobao.tbk.item.convert',
            'fields' => 'num_iid,click_url',//需返回的字段列表
            'num_iids' => 598727841028,//商品id
            'adzone_id' => $this->adzone_id,
            'platform' => 2,
            'uuid' => 'daoheng11',
        ];
        $result = $this->paramOrder($param);
        return \app('json')->success('ok', $result);
        $params = [
            'method' => 'taobao.tbk.sc.publisher.info.save',
            'app_key' => $this->appKey,
            'inviter_code' => 'E7LRL8',
            'info_type' => 1,
            'session' => '6100e225cf4b528ada9480835fe65910851a8aff24db8bd854372072',
            'note' => '保全',
            'timestamp' => date('Y-m-d H:i:s'),
            'format' => 'json',
            'v' => '2.0',
            'sign_method' => 'md5',
        ];
        ksort($params, SORT_STRING);
        $str = '';
        foreach ($params as $key => $value) {
            $str .= "{$key}{$value}";
        }
        $sign = strtoupper(md5("{$this->secretKey}{$str}{$this->secretKey}"));
        $params['sign'] = $sign;
        $url = 'http://gw.api.taobao.com/router/rest';
        $result = self::curlPost($url, $params);
//        $result = $this->paramOrder($params);
        return app("json")->success("生成relation编号", $result);
        halt('stop');
        //换取令牌
        $param = [
            'method' => 'taobao.top.auth.token.create',
            'code' => 'SHFth3YZmSypVNLMfsch2EvG975861',
        ];
        $result = $this->paramOrder($param);
        halt($result);


        $data = [
            'flag' => 'test',
            'content' => json_encode(request()->param(), JSON_UNESCAPED_UNICODE),
            'create_time' => time(),
        ];
        Db::name('run_log')->insert($data);
        halt('ok');
        //私域用户邀请码生成
        $param = [
            'method' => 'taobao.tbk.sc.invitecode.get',
            'relation_app' => 'app',
            'code_type' => 1,
        ];
        $result = $this->paramOrder($param);
        halt($result);

        //淘宝商品转链接
        $goodsId = '633554651124';
        $param = [
            'method' => 'taobao.tbk.item.convert',
            'fields' => 'num_iid,click_url',//需返回的字段列表
            'num_iids' => $goodsId,//商品id
            'adzone_id' => $this->adzone_id,
            'platform' => 2
        ];
        $result = $this->paramOrder($param);
        halt($result);

    }


    //发送curl请求方法
    public static function curlPost($url, $params)
    {
        $header = array(
            'Accept: application/json',
        );
        $curl = curl_init($url);
        //设置请求头
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
        //设置获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 5);
        $data = curl_exec($curl);
        if (curl_error($curl)) {
            return curl_error($curl);
        } else {
            curl_close($curl);
            return json_decode($data, true);
        }
    }

    /*物料分类*/
    public function getMaterial()
    {

        $result = $this->userThird->getMaterial();

        return app("json")->success($result);
    }


    /*创建广告位*/
    public function createPid($uid)
    {
        $param = [
            'method' => 'taobao.tbk.adzone.create',
            'site_id' => $uid,//商品id
            'adzone_name' => '人人享' . $uid
        ];
        $result = $this->paramOrder($param);
        var_dump($result);
        $result = $result['tbk_adzone_create_response']['data']['model'];
        if ($result) {
            $pid = array_filter(explode('_', 'mm_1_2_3'));
            $data =
                [
                    'pid' => $pid['3'],
                    'pid_name' => $result,
                    'create_time' => date("Y-m-d H:i:s"),
                    'type' => 5,
                    'uid' => $uid,
                ];
        }
        $pdd_id = $this->userThird->createPid($data);
        return $pdd_id;
    }


    /*订单*/
    public function orderOld()
    {
        $time = $this->request->params([
            'startTime',
            'endTime'
        ]);
        //自定义时间
        if (!$time['startTime'] && !$time['endTime']) {
            $time['startTime'] = strtotime('yesterday');
            $time['endTime'] = strtotime(date('Y-m-d')) - 1;
        }
        try {
            $orderLists = [];
            $page = 1;
            $pageSize = 20;
            do {
                $param = [
                    'method' => 'taobao.tbk.order.details.get',
                    'page_size' => $pageSize,
                    'page_no' => $page,
                    'start_time' => $time['startTime'],
                    'end_time' => $time['endTime'],
                    'jump_type' => 1 //跳转类型，当向前或者向后翻页必须提供,-1: 向前翻页,1：向后翻页
                ];
                $result = $this->paramOrder($param);
                $lists = $result['tbk_order_details_get_response']['data']['results'];
                $countList = count($lists);
                if (!empty($countList)) {
                    $orderLists = array_merge($orderLists, $lists);
                }
                $page++;
            } while ($countList == $pageSize);
            if (!empty($orderLists)) {
                //格式化从拼多多拉取的订单列表
                $formatLists = $this->formatOrderList($orderLists);
                //将拼多多订单列表中的订单进行处理
                $this->operatePinOrder($formatLists);
            }
            return app("json")->success("订单写入成功");
        } catch (\Exception $e) {
            return app("json")->fail($e->getMessage());
        }
    }

    /*格式化订单*/
    public function formatOrderList($orderLists)
    {
        $user = app()->make(UserThirdRepository::class);
        $formatLists = [];
        foreach ($orderLists as $order) {
            //订单关联推广位ID
            $pid = $order['orderStatus']['pid'] ?: '';
            if (empty($pid)) continue;
            $chanTag = $user->getDetail(['pid' => $order['pid'], 'type' => 3], 'uid,pid');
            $formatLists[] = [
                'uid' => $chanTag['uid'] ?? 0,
                'type' => 5,
                'pid' => $order['adzone_id'],
                'order_sn' => $order['trade_parent_id'],//买家在淘宝后台显示的订单编号
                'trade_id' => $order['trade_id'],//买家通过购物车购买的每个商品对应的订单编号，此订单编号并未在淘宝买家后台透出
                'pub_id' => $order['pub_id'],//推广者的会员id
                'item_id' => $order['item_id'],//商品id
                'item_img' => $order['item_img'],//图片
                'item_title' => $order['item_title'],//商品名称
                'item_num' => $order['item_img'],//数量
                'item_price' => $order['item_price'],//单价
                'seller_shop_title' => $order['seller_shop_title'],//店铺名称
                'pay_price' => $order['pay_price'],//买家确认收货的付款金额（不包含运费金额）
                'alipay_total_price' => $order['pay_price'],//买家拍下付款的金额（不包含运费金额）
                'tk_status' => $order['tk_status'],//状态已付款：指订单已付款，但还未确认收货 已收货：指订单已确认收货，但商家佣金未支付 已结算：指订单已确认收货，且商家佣金已支付成功 已失效：指订单关闭/订单佣金小于0.01元，订单关闭主要有：1）买家超时未付款； 2）买家付款前，买家/卖家取消了订单；3）订单付款后发起售中退款成功；3：订单结算，12：订单付款， 13：订单失效，14：订单成功
                'create_time' => $order['tk_paid_time'],//下单时间
                'tk_earning_time' => $order['tk_earning_time'],//订单确认收货后且商家完成佣金支付的时间
                'pub_share_rate' => $order['pub_share_rate'],//从结算佣金中分得的收益比率
                'tk_total_rate' => $order['tk_total_rate'],//提成=收入比率*分成比率。指实际获得收益的比率
                'income_rate' => $order['income_rate'],//订单结算的佣金比率+平台的补贴比率
                'commission_rate' => $order['total_commission_rate'],//佣金比率
                'commission' => $order['total_commission_fee'],//佣金金额=结算金额*佣金比率
            ];
        }
        return $formatLists;
    }


    /*处理订单*/
    public function operatePinOrder($orderLists)
    {

        $orderThird = app()->make(UserThirdRepository::class);
        foreach ($orderLists as $k => $order) {
            if (empty($order)) continue;
            //判断数据库有无此订单
            $orderVip = $orderThird->getOrderDetail("order_tb", ['order_sn' => $order['order_sn'], 'pid' => $order['pid']]);
            if (!$orderVip) {
                $order_id = $orderThird->createOrder('order_tb', $order); //订单写入数据库
            } else {
                if (($orderVip['tk_status' != $order['tk_status']])) {
                    $orderThird->saveOrder("order_tb", ['order_tb_id' => $orderVip['order_tb_id']],
                        [
                            'tk_status' => $order['tk_status'],
                            'tk_earning_time' => $order['tk_earning_time']
                        ]); //修改订单
                }
                $order_id = $orderVip['order_tb_id'];
            }

            //判断该订单是否符合返养老金条件(淘宝订单结算,佣金已结算)
            if ($order['tk_status'] == 3 && time() >= $orderVip['bill_end_time']) {
                //判断该订单是否已经返回过养老金
                if ($orderVip['bill_status'] == 0) {
                    $orderThird->successOrder($order_id, $order['commission'], $order['pid'], $order['order_sn'], 2, 'order_tb');
                }
            }
        }
    }

    //淘宝客授权
    public function getAuthUrl($state)
    {
        $authDomain = 'https://oauth.taobao.com/authorize';
        $params = [
            'client_id' => $this->appKey,
            'response_type' => 'code',
            'redirect_uri' => 'http://app.bjtdba.com/api/tb/callback',
            'state' => $state,
            'view' => 'wap',
        ];
        $urlParams = http_build_query($params);
        return "{$authDomain}?{$urlParams}";
    }

    //淘宝回调
    public function callback()
    {
        $code = request()->param('code', '');
        $state = request()->param('state', '');
        if (empty($state)) {
            return \app('json')->fail('传递的state状态不能为空');
        }
        list($userId, $goodsId) = explode('_', $state);
        if (empty($code)) {//如果没有获取到code需要用户重新授权
            redirect($this->getAuthUrl($state));
        }
        //获取Access Token
        $params = [
            'method' => 'taobao.top.auth.token.create',
            'code' => $code,
        ];
        $result = $this->paramOrder($params, true);
        $responseData = $result['top_auth_token_create_response']['token_result'] ?? '';
        if (empty($responseData)) {//拉取授权出错
            redirect($this->getAuthUrl($state));
        }
        $data = json_decode($responseData, true);
        $session = $data['access_token'];//获取token
        //生成渠道id完成渠道或会员的备案
        $params = [
            'method' => 'taobao.tbk.sc.publisher.info.save',
            'inviter_code' => 'E7LRL8',
            'info_type' => '1',
            'note' => "储_{$userId}",
            'session' => $session,
        ];
        $result = $this->paramOrder($params);
        $relationInfo = $result['tbk_sc_publisher_info_save_response']['data'] ?? [];
        if (empty($relationInfo)) {
            return \app('json')->fail('获取relation_id出错', $result);
        }
        $relationId = $relationInfo['relation_id'];
        $newThird = [
            'uid' => $userId,
            'pid' => $relationId,
            'pid_name' => $relationInfo['account_name'],
            'create_time' => time(),
            'type' => 5,
        ];
        $thirdResult = $this->userThird->createPid($newThird);
        if (empty($thirdResult)) {
            return \app('json')->fail('向user_third表中新增淘宝渠道编号绑定记录出错', $newThird);
        }
        //relation_id绑定成功后关闭百川页
        return view('/baichuan');
//        $result = DaTaoKe::changeLink($goodsId, $userId);
        //获取商品的转链链接
    }

    //获取access_token
    public function getToken($code, $state)
    {
        //获取Access Token
        $params = [
            'method' => 'taobao.top.auth.token.create',
            'code' => $code,
        ];
        $result = $this->paramOrder($params, true);
        $responseData = $result['top_auth_token_create_response']['token_result'] ?? '';
        if (empty($responseData)) {//拉取授权出错
            exception('//拉取授权出错', 401);
        }
        $data = json_decode($responseData, true);
        return $data['access_token'];//获取token
    }

    //生成渠道id
    public function makeRelation()
    {
        $params = [
            'method' => 'taobao.tbk.sc.publisher.info.save',
            'session' => '6101609cefe7edbb512b124f2c276bcf2530987f375022b187492153',
        ];
        $result = $this->paramOrder($params);
        return app("json")->success("订单写入成功", $result);
    }

}
