<?php

namespace App\Http\Controllers\QuickApp\Order;

use App\Consts\ErrorConst;
use App\Libs\Utils;
use App\Modules\Activity\Models\Activity;
use App\Modules\SendOrder\Models\QappSendOrder;
use App\Modules\Statistic\Services\AdVisitStatService;
use App\Http\Controllers\QuickApp\BaseController;
use App\Modules\User\Models\User;
use Illuminate\Http\Request;
use App\Modules\Subscribe\Services\BookOrderService;
use App\Modules\Subscribe\Services\ChapterOrderService;
use App\Modules\Subscribe\Services\OrderService;
use App\Http\Controllers\QuickApp\Order\Transformers\BookOrderTransformer;
use App\Http\Controllers\QuickApp\Order\Transformers\ChapterOrderTransformer;
use App\Http\Controllers\QuickApp\Order\Transformers\ChargeListTransformer;
use App\Libs\Pay\PayFactory;
use Hashids;
use App\Modules\Product\Services\ProductService;
use App\Modules\Book\Services\BookConfigService;
use App\Modules\Book\Services\BookService;
use App\Modules\Channel\Services\PayTemplateService;
use App\Modules\Subscribe\Models\Order;
use App\Modules\Trade\Models\Order as TradeOrder;
use App\Modules\Trade\Pay\OrderArousePayFactory;
use App\Modules\Trade\Pay\OrderPaySuccess;
use App\Modules\Trade\Services\PayMerchantService;
use App\Modules\User\Services\ReadRecordService;
use EasyWeChat\Support\XML;

class OrdersController extends BaseController
{
    /**
     * @apiDefine Order 订单
     */

    /**
     *
     */
    private $chargeList;

    public function exchangeList()
    {
        foreach ($this->chargeList as &$item) {
            if (!$item->switch_to) continue;
            $order = Order::where('uid', $this->uid)->where('status', 'PAID')->where('product_id', $item->id)->first();
            if ($order) {
                $change      = ProductService::getProductSingle($item->switch_to);
                $item->id    = $change->id;
                $item->price = $change->price;
                $item->given = $change->given;
            }
        }
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 充值列表
     * @api {get} order/chargeList 充值列表
     * @apiHeader {String} [Authorization]  token
     * @apiGroup Order
     * @apiName chargeList
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: [
     *               {
     *                   product_id: 1,
     *                   price: "30.00元",
     *                   vip: 0,
     *                   intro: [
     *                       {
     *                           label: 3000,
     *                           important: false
     *                       },
     *                       {
     *                           label: "书币",
     *                           important: true
     *                       }
     *                   ]
     *               },
     *               {
     *                   product_id: 2,
     *                   price: "50.00元",
     *                   vip: 1,
     *                   intro: [
     *                       {
     *                           label: 5000,
     *                           important: false
     *                       },
     *                       {
     *                           label: "1000+",
     *                           important: true
     *                       },
     *                       {
     *                           label: "书币",
     *                           important: false
     *                       }
     *                       ]
     *               },
     *               {
     *                   product_id: 5,
     *                   price: "365.00元",
     *                   vip: 0,
     *                   intro: [
     *                       {
     *                       label: "年费VIP会员",
     *                       important: true
     *                       }
     *                   ]
     *               }
     *               ]
     *       }
     */
    public function chargeList(Request $request)
    {
        $bid         = $request->input('bid', '');
        $temp        = $bid;
        $template_id = PayTemplateService::getPayTemplate($this->distribution_channel_id);

        // 获取派单id
        $sendOrderId = ReadRecordService::getSendOrderId($this->uid);
        if ($sendOrderId) {
            // 获取快应用账号
            $qappSendOrder = QappSendOrder::getSendOrderById($sendOrderId);
            $account       = getProp($qappSendOrder, 'account');

            // 注意！！！以后模板id加10000内的，不然可能会和渠道自定义的冲突
            // 方夏青的派单使用，男频充值模板
            if ($account === 'fangxq') {
                $template_id = 10666;
            }

            // 蒋佳芯
            if (in_array($account, ['jiangjx'])) {
                $template_id = 10679;
            }
            // 杨子航，zhoulj
            if (in_array($account, ['18668420256','yangzh'])) {
                $template_id = 9998;
            }

            if (in_array($account, ['hanyh', 'liwh', 'caicf', 'wangdd', 'zhangtt', 'hanyh2', 'hanyh33','zhangtt2','zhangtt33','zhangtt4'])) {
                $template_id = 9999;
            }
        }

        $book_config = null;
        if ($bid) {
            $bid         = Hashids::decode($bid)[0];
            $book_config = BookConfigService::getBookById($bid);
        }
        if ($template_id == 2) { //模板2只有在长篇小说过来的用户才显示
            //部分渠道需要2元模板不管哪个入口进来都展示
            $exclude_channels = explode(',', env('PRICE_TWO_SHOW_ALL_CHANNEL'));
            if (!in_array($this->distribution_channel_id, $exclude_channels)) {
                if ($book_config) {
                    if ($book_config->charge_type == 'BOOK') $template_id = 1;
                }
            }
        }
        $res = ProductService::getChargeProduct($template_id);
        if (!$res) {
            return response()->error('WAP_SYS_ERROR');
        }
        $this->chargeList = $res;
        $this->exchangeList();
        //TODO 长篇小数才有模板2
        $uid               = $this->uid;
        $is_first_recharge = OrderService::judgeUserFirstRecharge($uid);
        
        \Log::info('qappchargeList:uid:'.$uid.' send_order_id:'.$sendOrderId.' template_id:'.$template_id.' is_first_recharge:'.$is_first_recharge);

        $data  = [];
        $appad = 0;

        foreach ($res as $v) {
            if ($template_id == 7 && $book_config && $book_config->charge_type == 'BOOK' && $v->price == 2) {
                continue;
            }
            if ($template_id == 2 && $v->type == 'NEW_USER' && !$bid) {
                //2元模版，直接进充值，不出现
                continue;
            }
            if ($v->type == 'NEW_USER' && $is_first_recharge) {
                if (
                    env('NO_NEW_USER_CHARGE') &&
                    in_array(
                        $this->distribution_channel_id,
                        explode(',', env('NO_NEW_USER_CHARGE'))
                    )
                ) {
                    continue;
                }
                $temp   = [
                    'price'          => (float)$v->price . '元',
                    'is_year_order'  => 0,
                    'is_month_order' => 0,
                    'text'           => sprintf('%s+%s书币', $v->price * 100, $v->given),
                    'today_special'  => $v->is_default,
                    'first_charge'   => true,
                    'save_text'      => round($v->given / 100, 1) . '元',
                    'product_id'     => $v->id,
                ];
                $data[] = $temp;
            } elseif ($v->type == 'YEAR_ORDER') {
                if ($v->type == 'NEW_USER') {
                    continue;
                }
                $save_text = '年费vip会员';
                $text      = '全年免费看';
                $temp      = [
                    'price'          => (int)$v->price . '元',
                    'is_year_order'  => 1,
                    'is_month_order' => 0,
                    'text'           => $text,
                    'today_special'  => $v->is_default,
                    'first_charge'   => false,
                    'save_text'      => $save_text,
                    'product_id'     => $v->id,
                ];
                $data[]    = $temp;
            } else {
                if ($v->type == 'NEW_USER') {
                    continue;
                }
                $save_text = '';
                if ($v->given) {
                    $save_text = round($v->given / 100, 1) . '元';
                    $text      = sprintf('%s+%s书币', $v->price * 100, $v->given);
                } else {
                    $text = sprintf('%s书币', $v->price * 100);
                }

                $temp   = [
                    'price'          => (float)$v->price . '元',
                    'is_year_order'  => 0,
                    'is_month_order' => 0,
                    'text'           => $text,
                    'today_special'  => $v->is_default,
                    'first_charge'   => false,
                    'save_text'      => $save_text,
                    'product_id'     => $v->id,
                ];
                $data[] = $temp;
            }
        }
        return response()->success($data);
    }


    /**
     * @apiVersion 1.0.0
     * @apiDescription 单本消费记录
     * @api {get} order/bookOrderList 单本消费记录
     * @apiHeader {String} [Authorization]  token
     * @apiGroup Order
     * @apiName bookOrderList
     * @apiParam {String} [page_size]    分页大小
     * @apiParam {String} [page]          页码
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Int}         uid uid
     * @apiSuccess {Int}         bid bid
     * @apiSuccess {Int}         book_name 书名
     * @apiSuccess {Int}         fee 钱
     * @apiSuccess {String}      created_at 时间
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: list:[
     *               {
     *                   uid: 4,
     *                   bid: 1,
     *                   book_name: "dfsedfertrwet",
     *                   fee: 100,
     *                   created_at: "2017-12-02 16:24:54"
     *                   }
     *               ]
     *            meta: {
     *                       total: 1,
     *                       per_page: 15,
     *                       current_page: 1,
     *                       last_page: 1,
     *                       next_page_url: "",
     *                       prev_page_url: ""
     *               }
     *       }
     *       }
     */
    public function bookOrderList(Request $request)
    {
        $page_size  = $request->input('page_size', 15);
        $book_order = BookOrderService::getRecord($this->uid, $page_size);
        return response()->pagination(new BookOrderTransformer(), $book_order);
    }


    /**
     * @apiVersion 1.0.0
     * @apiDescription 章节消费记录
     * @api {get} order/chapterOrderList 章节消费记录
     * @apiHeader {String} [Authorization]  token
     * @apiGroup Order
     * @apiName chapterOrderList
     * @apiParam {String} [page_size]    分页大小
     * @apiParam {String} [page]          页码
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Int}         uid uid
     * @apiSuccess {Int}         bid bid
     * @apiSuccess {Int}         cid cid
     * @apiSuccess {Int}         chapter_name 章节名
     * @apiSuccess {Int}         book_name 书名
     * @apiSuccess {Int}         fee 钱
     * @apiSuccess {String}      created_at 时间
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: list:[
     *               {
     *                   uid: 4,
     *                   bid: 1,
     *                   cid: 1,
     *                   chapter_name: "sdfsd",
     *                   book_name: "dfsedfertrwet",
     *                   fee: 100,
     *                   created_at: "2017-12-02 16:24:54"
     *                   }
     *               ]
     *            meta: {
     *                       total: 1,
     *                       per_page: 15,
     *                       current_page: 1,
     *                       last_page: 1,
     *                       next_page_url: "",
     *                       prev_page_url: ""
     *               }
     *       }
     */
    public function chapterOrderList(Request $request)
    {
        $chapter_model = new ChapterOrderService();
        $page_size     = $request->input('page_size', 15);
        $chapter_order = $chapter_model->getByUid($this->uid, $page_size);
        foreach ($chapter_order as $item) {
            if ($item->fee == 0) {
                $result    = AdVisitStatService::getInfoV2($this->uid, $item->cid, ['UNLOCK', 'UNLOCK_2']);
                $item->fee = '解锁';
            }
        }
        return response()->pagination(new ChapterOrderTransformer(), $chapter_order);
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 充值记录
     * @api {get} order/chargeRecordLists 充值记录
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiGroup Order
     * @apiName chargeRecordLists
     * @apiParam {String} [page_size]    分页大小
     * @apiParam {String} [page]          页码
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {String}      data.price       价格
     * @apiSuccess {String}      data.status      状态
     * @apiSuccess {String}      data.trade_no    订单号
     * @apiSuccess {String}      data.created_at  时间
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *    {
     *       code: 0,
     *       msg: "",
     *           data: {
     *               list: [
     *               {
     *                    id: 134,
     *                    price: "1.00",
     *                    status: "PAID",
     *                    trade_no: "201712021915481585670623626232",
     *                    created_at: "2017-12-02 19:15:56"
     *           }
     *       ],
     *           meta: {
     *               total: 1,
     *               per_page: 15,
     *               current_page: 1,
     *               last_page: 1,
     *               next_page_url: "",
     *               prev_page_url: ""
     *           }
     *       }
     *    }
     */
    public function chargeRecordLists(Request $request)
    {
        $page_size = $request->input('page_size', 15);
        $res       = OrderService::getSuccessOrderList($this->uid, $page_size);
        return response()->pagination(new ChargeListTransformer(), $res);
    }


    private function getPayParams(Request $request)
    {
        $uid           = $this->uid;
        $product_id    = $request->get('product_id', 0);
        $send_order_id = $this->send_order_id;
        if (!$product_id) {
            return false;
        }
        $bid = $request->get('bid', 0);
        if ($bid) {
            $from_bid = BookService::decodeBidStatic($bid);
        }
        $trade_no = date("YmdHis") . hexdec(uniqid());
        myLog('pay-order')->info('request', [
            'params'   => $request->all(),
            'uid'      => $uid,
            'bid'      => $bid,
            'trade_no' => $trade_no
        ]);
        $product_info = ProductService::getProductSingle($product_id);
        if (!getProp($product_info, 'id')) {
            return false;
        }

        $distribution_channel_id = $this->distribution_channel_id;
        $price                   = $product_info->price * 100;
        if (in_array($uid, explode(',', env('TEST_UID')))) {
            $price = 1;
        }
        $from_type = 'QuickApp';
        if ($product_info->type == 'YEAR_ORDER') {
            $order_type = 'YEAR';
        } elseif ($product_info->type == 'QUARTER') {
            $order_type = 'QUARTER';
        } elseif ($product_info->type == 'BOOK_ORDER') {
            $order_type = 'BOOK';
        } elseif ($product_info->type == 'TICKET_RECHARGE') {
            $order_type = 'RECHARGE';
        } else {
            $order_type = '';
        }
        $create_ip = _getIp();

        // 活动
        $activity_token = $request->get('activity_token', '');
        $activity_id    = 0;
        if ($activity_token) {
            $activity    = Activity::getActivityBuToken($activity_token);
            $activity_id = (int)getProp($activity, 'id');

            // 校验活动次数
            $settingJson = getProp($activity, 'setting');
            if ($settingJson) {
                $setting      = json_decode($settingJson, true);
                $productInfos = getProp($setting, 'product_info', []);
                $productInfo  = collect($productInfos)->firstWhere('product_id', $product_id);
                $limit        = (int)getProp($productInfo, 'limit');
                if ($limit > 0) {
                    // 查询用户通过该活动已经充值的次数
                    $paidNum = TradeOrder::getActivityOrderNum([
                        'uid'         => $uid,
                        'begin_time'  => getProp($activity, 'start_time'),
                        'end_time'    => getProp($activity, 'end_time'),
                        'status'      => 'PAID',
                        'product_id'  => $product_id,
                        'activity_id' => $activity_id
                    ]);
                    myLog('charge')->info('', compact('uid', 'product_id', 'activity', 'paidNum'));

                    // 活动充值次数限制
                    if ($paidNum >= $limit) {
                        Utils::throwError(ErrorConst::ACTIVITY_CHARGE_OUT_OF_LIMIT);
                    }
                }
            }
        }

        // 包名
        $package = $request->header('x-package', '');

        return compact(
            'distribution_channel_id',
            'uid',
            'product_id',
            'price',
            'trade_no',
            'create_ip',
            'send_order_id',
            'from_bid',
            'from_type',
            'order_type',
            'activity_id',
            'package'
        );
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 支付
     * @api {get} goToPay 微信APP支付
     * @apiGroup pay
     * @apiName wxindex
     * @apiParam {Int}  product_id   product_id
     * @apiParam {Int}  send_order_id   send_order_id
     * @apiParam {String}  bid   bid
     * @apiHeader {String} [Authorization]  token
     * @apiSuccess {int}   code 状态码
     * @apiSuccess {String}  msg 信息
     * @apiSuccess {Object}  data 信息
     * @apiSuccess {Object}  data.trade_no 订单号
     * @apiSuccess {Object}  data.appId 唤起支付的appId
     * @apiSuccess {Object}  data.mch_id 唤起支付的mch_id
     * @apiSuccess {Object}  data.nonce_str 唤起支付的nonce_str
     * @apiSuccess {Object}  data.prepay_id 唤起支付的prepay_id
     * @apiSuccess {Object}  data.sign 唤起支付的sign
     * @apiSuccess {Object}  data.trade_type 唤起支付trade_type
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: {
     *
     *       }
     */
    function wxIndex(Request $request)
    {
        if ($params = $this->getPayParams($request)) {
            $params['pay_merchant_id'] = $this->app_pay_merchat_id;
        } else {
            return response()->error('QAPP_PARAM_ERROR');
        }
        $app = OrderArousePayFactory::wx($this->uid);
        // 微信支付参数
        $params['trade_type'] = 'APP'; //交易类型
        $result               = $app->handle($params);
        myLog('wxPay')->info('wxIndex', compact('params', 'result'));
        if ($result) {
            $result['trade_no'] = $params['trade_no'];
            return response()->success($result);
        } else {
            return response()->error('APP_CREATE_WECHAT_ORDER_FAIL');
        }
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 微信H5支付
     * @api {get} goToH5Pay 微信H5支付
     * @apiGroup pay
     * @apiName wxH5Index
     * @apiParam {Int}  product_id   product_id
     * @apiParam {Int}  send_order_id   send_order_id
     * @apiParam {String}  bid   bid
     * @apiHeader {String} [Authorization]  token
     * @apiSuccess {int}   code 状态码
     * @apiSuccess {String}  msg 信息
     * @apiSuccess {Object}  data 信息
     * @apiSuccess {Object}  data.trade_no 订单号
     * @apiSuccess {Object}  data.appId 唤起支付的appId
     * @apiSuccess {Object}  data.mch_id 唤起支付的mch_id
     * @apiSuccess {Object}  data.nonce_str 唤起支付的nonce_str
     * @apiSuccess {Object}  data.prepay_id 唤起支付的prepay_id
     * @apiSuccess {Object}  data.sign 唤起支付的sign
     * @apiSuccess {Object}  data.trade_type 唤起支付trade_type
     * @apiSuccess {Object}  data.mweb_url 唤起支付mweb_url
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: {
     *
     *       }
     */
    function wxH5Index(Request $request)
    {
        if ($params = $this->getPayParams($request)) {
            $params['pay_merchant_id'] = $this->h5_pay_merchat_id;
        } else {
            return response()->error('QAPP_PARAM_ERROR');
        }
        $app = OrderArousePayFactory::wx($this->uid);
        // 微信支付参数
        $params['trade_type'] = 'MWEB'; //交易类型
        $result               = $app->handle($params);
        myLog('wxPay')->info('wxH5Index', compact('params', 'result'));
        if ($result) {
            $result['trade_no'] = $params['trade_no'];
            return response()->success($result);
        } else {
            return response()->error('APP_CREATE_WECHAT_ORDER_FAIL');
        }
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 支付宝APP支付
     * @api {get} goToAliPay 支付宝APP支付
     * @apiGroup pay
     * @apiName aliIndex
     * @apiParam {Int}  product_id   product_id
     * @apiParam {Int}  send_order_id   send_order_id
     * @apiParam {String}  bid   bid
     * @apiHeader {String} [Authorization]  token
     * @apiSuccess {Object}  data.order_info 唤起支付信息str
     * @apiSuccess {Object}  data.trade_no 订单号
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data:""
     *
     */
    public function aliIndex(Request $request)
    {
        myLog('aliPay')->info('aliIndex-request', [$request->all()]);
        if ($params = $this->getPayParams($request)) {
            myLog('aliPay')->info('aliIndex-request1', compact('params'));
            $params['pay_merchant_id'] = $this->ali_pay_merchat_id;
            $params['type']            = 'App';
            myLog('aliPay')->info('aliIndex-request2', compact('params'));
        } else {
            return response()->error('QAPP_PARAM_ERROR');
        }
        $app        = OrderArousePayFactory::ali($this->uid);
        $order_info = $app->handle($params);
        myLog('aliPay')->info('aliIndex', compact('params', 'order_info'));
        return response()->success(['trade_no' => $params['trade_no'], 'order_info' => $order_info]);
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 订单查询
     * @api {get} checkOrder 订单查询
     * @apiGroup pay
     * @apiName checkOrder
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiParam {String}  order   order
     * @apiSuccess {int}   code 状态码
     * @apiSuccess {String}  msg 信息
     * @apiSuccess {Object}  data 信息
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: {
     *
     *       }
     */
    public function checkOrder(Request $request)
    {
        $order      = $request->input('order');
        $order_info = OrderService::getByTradeNo($order);
        if ($order_info && $order_info->status == 'PAID') {
            return response()->success();
        }
        return response()->success($order);
    }

    /**
     * 官方微信回调
     */
    function wxback(Request $request)
    {
        $xml = XML::parse(strval($request->getContent()));
        myLog('wxpay')->info($xml);
        if (isset($xml['attach'])) {
            $pay_merchant_id = (int)$xml['attach'];
            $config          = PayMerchantService::findPayConfig($pay_merchant_id);
            $app             = PayFactory::official($config);
            $response        = $app->notify()->handleNotify(function ($notify, $successful) {
                if (!$successful) {
                    return 'fail';
                }
                if (OrderPaySuccess::handle($notify->out_trade_no, $notify->transaction_id)) {
                    return true;
                } else {
                    return 'fail';
                }
            });
            return $response;
        } else {
            return 'fail';
        }
    }

    /**
     * 支付宝支付回调
     */
    function aliback(Request $request)
    {
        $param = $request->except('_url');
        myLog('alipay')->info($param);
        $trade_no = isset($param['out_trade_no']) ? $param['out_trade_no'] : '';
        if ($trade_no) {
            $order           = Order::where('trade_no', $trade_no)->first();
            $pay_merchant_id = $order ? $order->pay_merchant_id : 0;
            $pay_merchant_id = $pay_merchant_id ? $pay_merchant_id : 140;
            $config          = PayMerchantService::findAliPayConfig($pay_merchant_id);
            $app             = PayFactory::aliPay($config);
            if ($app->notify($param)) {
                if (OrderPaySuccess::handle($param['out_trade_no'], $param['trade_no'])) {
                    return response('success');
                } else {
                    return response('fail');
                }
            }
        }
        myLog('alipay')->info('sign fail');
        return response('fail');
    }

    function wait(Request $request)
    {
        $param = $request->except('_url');
        return view('pay.middleware')->with($param);
    }
}
