<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/9/21
 * Time: 16:53
 */

namespace app\api\controller;

use think\Db;
use think\Loader;
use think\Validate;
use app\common\model\Project as ProjectModel;
use app\common\model\Order as OrderModel;
use app\common\model\User as UserModel;
use app\common\model\Refund as RefundModel;

Loader::import('wxpay.Api');

class Order extends Base
{
    /**
     * 活动下单
     * @url /api/Order/projectOrder
     * @param pid
     * @param nickname
     * @param phone
     * @param adult_number
     * @param children_number
     * @param children_age
     * @param sign_limits
     * @param remark
     * @return json
     */
    public function projectOrder()
    {

        //检验参数
        $validate = Validate::make([
            'pid'             => 'require',
            'nickname'        => 'require',
            'phone'           => 'require',
            'adult_number'    => 'require',
            'children_number' => 'require',
            'children_age'    => 'require',
            'sign_limits'     => 'require'
        ]);
        $res      = $validate->check(input('post.'));
        if (!$res) return ['code' => 1, 'msg' => $validate->getError()];
        $project = ProjectModel::get(input('post.pid'));
        if (!$project) {
            return ['code' => 1, 'msg' => '该活动不存在'];
        }
        //检验该活动是否有效期
        if (time() > strtotime($project->sign_endtime)) {
            //活动过期
            return ['code' => 1, 'msg' => '活动已截止报名'];
        }
        //生成订单
        try {
            //开始事务
            Db::startTrans();
            //检验家庭组限制->已上锁
            $res = OrderModel::getGroupNumberByProject(input('post.pid'), input('post.sign_limits'));
            if (!$res) throw new \Exception('该活动报名已满!');
            //生成订单入库
            $order        = new OrderModel();
            $order->type  = config('order_type.project');
            $order->uid   = $this->userinfo[0];
            $order->pid   = $project['id'];
            $order->title = $project['title'];
            //查看是否为会员
            $user = UserModel::get($this->userinfo[0]);
            //活动总价
            $price            = $user['is_vip'] ? $project['price'] : $project['vip_price'];
            $order->total_fee = $price * 100 * input('post.sign_limits') / 100;
            //TODO::支付状态应该是noPay,测试换成pay
            $order->status = config('order_status.pay');
            // $order->status    = config('order_status.no_pay');
            $order->extras = [
                'nickname'        => input('post.nickname'),
                'phone'           => input('post.phone'),
                'adult_number'    => input('post.adult_number'),
                'children_number' => input('post.children_number'),
                'children_age'    => input('post.children_age'),
                'sign_limits'     => input('post.sign_limits'),
                'price'           => $price,
                'remark'          => input('post.remark'),
            ];
            if (!$order->save()) {
                throw new \Exception('报名失败,请稍后再试');
            }
            $data['order_id']  = intval($order->id);
            $data['total_fee'] = doubleval($order->total_fee);
            //生成订单
            //TODO::关闭支付接口
            // 更新订单号-防止签名失败
            // $order->out_trade_no = (new \WxPayConfig())->GetMerchantId() . time() . $order->id;

            // $input = new \WxPayUnifiedOrder();
            // $input->SetBody($order->title);
            // $input->SetAttach($order->id);
            // $input->SetOut_trade_no($order->out_trade_no);
            // $input->SetTotal_fee(floatval($order->total_fee) * 100);  // 单位为分
            // $input->SetTime_start(date("YmdHis"));
            // $input->SetTime_expire(date("YmdHis", time() + 600));
            // //$input->SetGoods_tag("wx-xcx");
            // $input->SetNotify_url(config('wx_pay.notify_url'));
            // $input->SetTrade_type("JSAPI");
            // $input->SetOpenid($this->userinfo[1]);
            // $unifiedOrder = \WxPayApi::unifiedOrder($input);
            // if ($unifiedOrder["return_code"] == 'FAIL') {
            //     return ['code' => 1, 'msg' => $unifiedOrder['return_msg']];
            // }
            // // 保存 prepay_id 用于发送模版消息
            // $order->prepay_id = $unifiedOrder['prepay_id'];
            // $order->save();
            // $jsApiParameters = $this->GetJsApiParameters($unifiedOrder);
            // if ($jsApiParameters) {
            //     return ['code' => 0, 'msg' => '支付参数', 'data' => $data, 'result' => json_decode($jsApiParameters)];
            // } else {
            //     throw new \Exception('订单签名失败');
            // }


            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'msg' => $e->getMessage()];
        }

        //TODO::删除伪成功
        return ['code' => 0, 'msg' => '报名成功'];
    }

    /**
     * vip购买
     * @url /api/Order/vipOrder
     * @param year
     * @return json
     */
    public function vipOrder()
    {

        //检验参数
        $validate = Validate::make([
            'year' => 'require',
        ]);
        $res      = $validate->check(input('post.'));
        if (!$res) return ['code' => 1, 'msg' => $validate->getError()];
        //生成订单

        try {
            //开始事务
            Db::startTrans();
            $year = intval(input('post.year'));
            //生成订单入库
            $order        = new OrderModel();
            $order->type  = config('order_type.vip');
            $order->uid   = $this->userinfo[0];
            $order->title = config('wx_pay.vip_title');
            //活动总价
            $order->total_fee = config('wx_pay.vip_price') * 100 * $year / 100;
            //查看vip有效期
            $user = UserModel::get($this->userinfo[0]);
            if ($user->is_vip == 1) {
                if (strtotime($user->vip_endtime) > time()) {//累加
                    $vip_endtime = strtotime("{$user->vip_endtime} +{$year} year");
                } else {
                    $vip_endtime = strtotime("+{$year} year");
                }
            } else {
                $vip_endtime = strtotime("+{$year} year");
            }
            $vip_endtime = date('Y-m-d H:i:s', $vip_endtime);
            //TODO::支付状态应该是noPay,测试换成pay
            $order->status = config('order_status.pay');
            // $order->status = config('order_status.no_pay');
            $order->extras = [
                'year'        => $year,
                'vip_endtime' => $vip_endtime,
                'price'       => config('wx_pay.vip_price'),
                'remark'      => input('post.remark'),
            ];
            if (!$order->save()) {
                throw new \Exception('购买失败,请稍后再试');
            }
            $data['order_id']  = intval($order->id);
            $data['total_fee'] = doubleval($order->total_fee);
            //生成订单
            //TODO::关闭支付接口
            // // 更新订单号-防止签名失败
            // $order->out_trade_no = (new \WxPayConfig())->GetMerchantId() . time() . $order->id;
            //
            // $input = new \WxPayUnifiedOrder();
            // $input->SetBody($order->title);
            // $input->SetAttach($order->id);
            // $input->SetOut_trade_no($order->out_trade_no);
            // $input->SetTotal_fee(floatval($order->total_fee) * 100);  // 单位为分
            // $input->SetTime_start(date("YmdHis"));
            // $input->SetTime_expire(date("YmdHis", time() + 600));
            // // $input->SetGoods_tag("wx-xcx");
            // $input->SetNotify_url(config('wx_pay.notify_url'));
            // $input->SetTrade_type("JSAPI");
            // $input->SetOpenid($this->userinfo[1]);
            // $unifiedOrder = \WxPayApi::unifiedOrder($input);
            // if ($unifiedOrder["return_code"] == 'FAIL') {
            //     return ['code' => 1, 'msg' => $unifiedOrder['return_msg']];
            // }
            // // 保存 prepay_id 用于发送模版消息
            // $order->prepay_id = $unifiedOrder['prepay_id'];
            // $order->save();
            // $jsApiParameters = $this->GetJsApiParameters($unifiedOrder);
            // if ($jsApiParameters) {
            //     return ['code' => 0, 'msg' => '支付参数', 'data' => $data, 'result' => json_decode($jsApiParameters)];
            // } else {
            //     throw new \Exception('订单签名失败');
            // }
            //TODO::删除测试代码  --------------------开始

            $user              = UserModel::get($this->userinfo[0]);
            $user->is_vip      = 1;
            $user->vip_endtime = $vip_endtime;
            $user->save();
            //----------------------------------------结束

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 1, 'msg' => $e->getMessage()];
        }

        //TODO::删除伪成功
        return ['code' => 0, 'msg' => '开通成功'];
    }

    /**
     *
     * 获取jsapi支付的参数
     * @param array $UnifiedOrderResult 统一支付接口返回的数据
     * @throws WxPayException
     * @return json数据，可直接填入js函数作为参数
     */
    private function GetJsApiParameters($UnifiedOrderResult)
    {
        if (!array_key_exists("appid", $UnifiedOrderResult)
            || !array_key_exists("prepay_id", $UnifiedOrderResult)
            || $UnifiedOrderResult['prepay_id'] == "") {
            return null;
        }
        $jsapi = new \WxPayJsApiPay();
        $jsapi->SetAppid($UnifiedOrderResult["appid"]);
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(\WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $parameters = json_encode($jsapi->GetValues());
        return $parameters;
    }

    /**
     * 微信支付回调接口，由微信服务器主动调用
     * @return xml
     */
    public function callback()
    {
        $xml  = file_get_contents("php://input");
        $data = \WxPayResults::Init($xml);
        if (!array_key_exists("transaction_id", $data)) {
            echo $this->toXML(['return_code' => 'FAIL', 'return_msg' => '参数错误']);
            exit;
        }
        // 查询订单，判断订单真实性
        if (!$data["out_trade_no"] || !$this->Queryorder($data["transaction_id"])) {
            echo $this->toXML(['return_code' => 'FAIL', 'return_msg' => '订单真实性存疑']);
            exit;
        }
        $order = OrderModel::where(['out_trade_no' => $data["out_trade_no"]])->find();
        if (!$order) {
            echo $this->toXML(['return_code' => 'FAIL', 'return_msg' => '订单不存在']);
            exit;
        }

        $succeed = false;
        Db::startTrans();
        try {
            // 订单状态更新 - 已支付
            $order->status       = config("order_status.pay");
            $order->trade_status = 'SUCCESS';
            $order->save();
            if ($order->type == config('order_type.vip')) {
                //给user表加数据
                $user              = UserModel::get($this->userinfo[0]);
                $user->is_vip      = 1;
                $user->vip_endtime = $order['extras']['end_time'];
                $user->save();
            }
            // 提交事务
            Db::commit();

            $succeed = true;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $succeed = false;
        }

        if ($succeed) {
            echo $this->toXML(['return_code' => 'SUCCESS', 'return_msg' => 'OK']);
        } else {
            echo $this->toXML(['return_code' => 'FAIL', 'return_msg' => '回调失败']);
        }
    }

    /**
     * 查询订单
     *
     * @param [type] $transaction_id
     * @return void
     */
    private function Queryorder($transaction_id)
    {
        $input = new \WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);
        $result = \WxPayApi::orderQuery($input);
        if (array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS") {
            return true;
        }
        return false;
    }

    /**
     * 获取vip一年价格
     * @url /api/Order/getVipPrice
     * @return json
     */
    public function getVipPrice()
    {
        return ['code' => 1, 'msg' => 'success', 'price' => number_format(config('wx_pay.vip_price'), 2)];
    }

    /**
     * 订单列表
     * @param p 页数
     * @param page 每页几条
     * @param status 状态
     * @return json
     */
    public function index()
    {
        $p      = input('post.p/d', 1);
        $page   = input('post.page/d', 8);
        $status = input('post.status/d', 1);
        $order  = OrderModel::with('project')
            ->where('status', $status)
            ->where('uid', $this->userinfo[0])
            ->where('type', 1)
            ->page($p, $page)
            ->select();
        $order  = collection($order);
        if ($order->isEmpty()) {
            return ['code' => 1, 'msg' => '没有更多'];
        }
        $order->visible(['id', 'pid', 'title', 'total_fee', 'project.poster', 'created_at', 'status', 'is_refund', 'is_comment'])->append(['status_text'])->toArray();
        return ['code' => 0, 'msg' => 'success', 'data' => $order];
    }

    /**
     * 退款申请
     * @url /api/Order/refundSubmit
     * @param id 订单id
     * @return json
     */
    public function refundSubmit()
    {
        $id    = input('post.id/d');
        $order = OrderModel::where('id', $id)
            ->where('uid', $this->userinfo[0])
            ->where('type', config('order_type.project'))
            ->where('status', config('order_status.pay'))
            ->where('is_refund','in', [config('refund_status.no'), config('refund_status.no_pass')])
            ->find();
        if (!$order) return ['code' => 1, 'msg' => '订单错误'];
        $order->is_refund = config('refund_status.to_examine');
        $order->save();
        //提交退款表
        RefundModel::create([
            'order_id' => $order->id,
            'uid'      => $this->userinfo[0]
        ]);
        return ['code' => 0, 'msg' => 'success'];
    }
}