<?php
namespace app\common\service;

use addons\epay\library\Service;
use fast\Random;
use think\Db;
use think\Exception;

class OrderService
{
    private $model =  null;

    /**
     * 初始化方法
     */
    public function __construct()
    {
        $this->model = Db::name('order');
    }

    /**
     * 套餐支付
     * @param $params
     * @return array
     */
    public function orderPay($params=[])
    {
        $result = [
            'status' => 1,
            'msg' => '操作成功',
            'data' => [],
        ];
        try {
            $payType   = isset($params['pay_type']) ? $params['pay_type'] : 'wechat';
            $platform  = isset($params['platform']) ? $params['platform'] : 'miniapp';
            $userId    = isset($params['user_id']) ? $params['user_id'] : 0;
            $carId     = isset($params['car_id']) ? $params['car_id'] : 0;
            $companyId = isset($params['company_id']) ? $params['company_id'] : 0;
            $packageId = isset($params['package_id']) ? $params['package_id'] : 0;
            $miniOpenId = isset($params['mini_openid']) ? $params['mini_openid'] : '';

            //验证车辆
            $userCarWhere['user_id'] = $userId;
            $userCarWhere['id'] = $carId;
            $userCar = Db::name('user_car')->where($userCarWhere)->find();
            if (empty($userCar)) {
                throw new Exception('未找到车辆信息');
            }
            //验证套餐
            $packageWhere['id'] = $packageId;
            $packageWhere['status'] = 1;
            $packageWhere['num'] = ['gt',0];
            $package = Db::name('package')->where($packageWhere)->find();
            if (empty($package)) {
                throw new Exception('未找到套餐信息');
            }
            /*if ($package['company_id'] != $companyId) {
                throw new Exception('您绑定的门店和购买套餐门店不一致');
            }*/
            if ($payType == 'wallet') {//验证余额
                $userWalletWhere['user_id'] = $userId;
                $userWalletWhere['company_id'] = $companyId;
                $userWallet = Db::name('user_wallet')->where($userWalletWhere)->find();
                if (empty($userWallet)) {
                    throw new Exception('钱包异常');
                }
                if ($userWallet['money'] < $package['price']) {
                    throw new Exception('您的余额不足,请充值。');
                }
            }

            $gift_amount = 0.00;
            $order_amount = $package['price'];
            $extData = ['car_id'=>$carId];
            $time = time();
            //创建订单
            $data['company_id'] = $companyId;
            $data['user_id'] = $userId;
            $data['out_trade_no'] = createUniqueNo('O',$userId); // 数据库订单号加密
            $data['order_amount'] = $order_amount;
            $data['gift_amount'] = $gift_amount;
            $data['createtime'] = time();
            $data['pay_type'] = $payType;
            $data['order_status'] = 0;
            $data['table_name'] = 'package';
            $data['table_id'] = $packageId;
            $data['ext_data'] = json_encode($extData);

            $payOrderId = Db::name('pay_order')->insertGetId($data);
            //支付方式:wallet=钱包,wechat=微信
            if ($payType == 'wechat') {//微信支付 记录日志,生成订单,商家端操作完成增加收入
                $httpStr = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'];
                //下单
                $payTest = config('param.pay_test');
                $orderAmount = $payTest == 1 ? 0.01 : $data['order_amount'];
                $paramsData = [
                    'type'      => $payType,
                    'orderid'   => $data['out_trade_no'],
                    'title'     => '购买套餐',
                    'amount'    => $orderAmount,
                    'method'    => $platform,
                    'openid'    => $miniOpenId,
                    'notifyurl' => $httpStr.'/api/pay/order_notify_base/paytype/'.$payType.'/func/package_do',
                    'returnurl' => '',
                ];

                $resData = Service::submitOrder($paramsData);
                $resData = json_decode($resData,true);
            } else {//余额支付 扣减余额,记录日志,生成订单 商家端不变
                //扣减金额
                $oldMoney = $userWallet['money'];
                $newMoney = bcsub($oldMoney,$package['price'],2);
                $userWalletData['money'] = $newMoney;
                $userWalletData['updatetime'] = $time;
                $userWalletWhere['user_id'] = $userId;
                $userWalletWhere['company_id'] = $companyId;
                $userWalletRes = Db::name('user_wallet')->where($userWalletWhere)->update($userWalletData);
                if (!$userWalletRes) {
                    throw new Exception('支付失败');
                }
                //余额明细记录
                $userMoneyLogData = [
                    'company_id' => $companyId,
                    'user_id' => $userId,
                    'log_type' => 103,//购买套餐
                    'before' => $oldMoney,
                    'change_value' => $package['price'],
                    'remain' => $newMoney,
                    'table' => 'pay_order',
                    'table_id' => $payOrderId,
                    'remark' => '购买套餐',
                    'createtime' => $time,
                    'updatetime' => $time,
                ];
                $userMoneyLogRes = Db::name('user_money_log')->insertGetId($userMoneyLogData);
                if (!$userMoneyLogRes) {
                    throw new Exception('余额明细记录失败');
                }
                //生成订单
                $params['order_paytype'] = 2;//支付方式:1=线下,2=余额,3=微信
                $params['pay_order_id'] = $payOrderId;
                $orderRes = $this->addOrder($params);
                if (!$orderRes['status']) {
                    throw new Exception($orderRes['msg']);
                }
                //更新支付状态
                $payOrderData['order_status'] = 1;
                $payOrderWhere['id'] = $payOrderId;
                $payOrderRes = Db::name('pay_order')->where($payOrderWhere)->update($payOrderData);
                if (!$payOrderRes) {
                    throw new Exception('支付失败');
                }
            }
            $resData['order_id'] = isset($orderRes['data']['order_id']) ? $orderRes['data']['order_id'] : 0;
            $resData['pay_order_id'] = $payOrderId;
            $resData['template_ids'] = config('param.wechat_template_ids');//微信消息模版ID
            $result['data'] = $resData;
        } catch (Exception $e) {
            $result['status'] = 0;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }

    /**
     * 生成订单
     * @return void
     */
    public function addOrder($params)
    {
        $result = [
            'status' => 1,
            'msg' => '操作成功',
            'data' => [],
        ];
        try {
            $packageId = isset($params['package_id']) ? $params['package_id'] : 0;
            $companyId = isset($params['company_id']) ? $params['company_id'] : 0;
            $userId    = isset($params['user_id']) ? $params['user_id'] : 0;
            $carId     = isset($params['car_id']) ? $params['car_id'] : 0;
            $payOrderId= isset($params['pay_order_id']) ? $params['pay_order_id'] : 0;
            $orderPayType = isset($params['order_paytype']) ? $params['order_paytype'] : 3;//支付方式:1=线下,2=余额,3=微信
            //生成订单
            $time = time();
            $packageWhere['id'] = $packageId;
            $packageWhere['num'] = ['gt',0];
            $package = Db::name('package')->where($packageWhere)->lock(true)->find();
            if (empty($package)) {
                throw new Exception('未找到套餐信息');
            }
            $userWhere['id'] = $userId;
            $user = Db::name('user')->where($userWhere)->find();
            //绑定门店
            $userService = new UserService();
            $userParams = [
                'user_id' => $userId,
                'company_id' => $companyId,
                'comefrom' => '平台引流',//来源
            ];
            $userBindRes = $userService->userWallet($userParams);
            if (!$userBindRes['status']) {
                throw new Exception($userBindRes['msg']);
            }
            $userCarWhere['id'] = $carId;
            $userCar = Db::name('user_car')->where($userCarWhere)->find();
            //生成订单
            $checkCode[] = Random::alnum(8);
            $orderService = new OrderService();//防重复
            $checkCodeRes = $orderService->getCheckOrder($checkCode);
            if ($checkCodeRes['status']) {
                $checkCodeStr = isset($checkCodeRes['data'][0]) ? $checkCodeRes['data'][0] : '';
            } else {
                $checkCodeStr = Random::alnum(8);
            }
            if ($package['type'] == 2) {//卡券类型直接已完成
                $orderStatus = 3;
                $finishTime = $time;
                $userCouponsParams = [
                    'package_id' => $packageId,
                    'company_id' => $companyId,
                    'user_id'    => $userId,
                    'payorder_id'=> $payOrderId,
                ];
                $userCouponsRes = $userService->packageCoupons($userCouponsParams);
                if (!$userCouponsRes['status']) {
                    throw new Exception($userCouponsRes['msg']);
                }
            } else {
                $orderStatus = 1;
                $finishTime = 0;
            }
            $orderData = [
                'check_code'      => $checkCodeStr,
                'orderno'         => createUniqueNo('O', $userId),//订单号
                'ordertype'       => 3,//类型:1=预约下单,2=在线下单,3=套餐订单
                'company_id'      => $companyId,//门店ID
                'user_id'         => $userId,//用户ID
                'user_name'       => isset($user['nickname']) ? $user['nickname'] : '',//用户姓名
                'user_car_id'     => isset($userCar['id']) ? $userCar['id'] : 0,//车辆ID
                'user_car_number' => isset($userCar['car_number']) ? $userCar['car_number'] : '',//用户车牌
                'user_mobile'     => isset($user['mobile']) ? $user['mobile'] : '',//用户手机
                'pre_order_id'    => 0,//预约单ID
                'package_id'      => isset($package['id']) ? $package['id'] : 0,//套餐ID
                'servicetype_id'  => isset($package['servicetype_id']) ? $package['servicetype_id'] : 0,//服务类型
                'server_info'     => isset($package['title']) ? $package['title'] : '',//套餐主标题
                'server_images'   => isset($package['images']) ? $package['images'] : '',//套餐图片
                'pay_fee'         => isset($package['price']) ? $package['price'] : 0.00,//套餐价格
                'status'          => $orderStatus,//状态:1=待核销,2=已接单,3=已完成,4=已取消
                'pay_time'        => $time,
                'paytype'         => $orderPayType,//支付方式:1=线下,2=余额,3=微信
                'total_fee'       => isset($package['price']) ? $package['price'] : 0.00,//支付总额
                'createtime'      => $time,//下单时间
                'pay_order_id'    => $payOrderId,//支付ID
                'finish_time'     => $finishTime,//完成时间
            ];
            $orderRes = Db::name('order')->insertGetId($orderData);
            if (!$orderRes) {
                throw new Exception('生成订单失败');
            }
            $newNum = $package['num'] - 1;
            $packageRes = Db::name('package')->where($packageWhere)->update(['num'=>$newNum]);
            if (!$packageRes) {
                throw new Exception('扣减库存失败');
            }
            $result['data'] = [
                'order_id' => $orderRes,
                'pay_order_id' => $payOrderId,
            ];
        } catch (Exception $e) {
            $result['status'] = 0;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }
    
    /**
     * 获取车辆预计下次保养时间
     * @return void
     */
    public function getCarNextDate($params=[])
    {
        $result = [
            'status' => 1,
            'msg' => '获取成功',
            'data' => [],
        ];
        try {
            $userId = isset($params['user_id']) ? $params['user_id'] : 0;
            $companyId = isset($params['company_id']) ? $params['company_id'] : 0;
            $carId = isset($params['car_id']) ? $params['car_id'] : [];
            $carNumber = isset($params['car_number']) ? $params['car_number'] : [];
            if (!empty($carNumber)) {
                $orderWhere['user_car_number'] = ['in',$carNumber];
            } else {
                $orderWhere['user_car_id'] = ['in',$carId];
            }
            $orderWhere['user_id'] = $userId;
            $orderWhere['company_id'] = $companyId;
            $orderWhere['next_date'] = ['neq',''];
            $orderWhere['status'] = 3;//状态:2=已接单,3=已完成,4=已取消
            $subQuery = Db::name('order')->alias('o')->where($orderWhere)
                ->order(['finish_time' => 'desc'])
                ->buildSql(); //构建查询语句

            $order = Db::table($subQuery)->alias('o')->field('id,user_car_id,user_car_number,next_date')
                ->group('user_car_id')->order('finish_time desc')->select();
            $row = [];
            if (!empty($order)) {
                foreach ($order as $key => $value) {
                    $row[$value['user_car_number']]['next_date'] = $value['next_date'];
                }
            }
            $result['data'] = $row;
        } catch (Exception $e) {
            $result['status'] = 0;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }

    /**
     * 查看是否重复-卡券
     * @return void
     */
    public function getCheckCoupons($checkCode=[])
    {
        try {
            if (!empty($checkCode)) {
                $where['check_code'] = ['in', $checkCode];
                $userCoupons = Db::name('user_coupon')->field('id,check_code')->where($where)->select();
                if (!empty($userCoupons)) {
                    $checkCodeDbArr = array_column($userCoupons,'check_code');
                    foreach ($checkCode as $key => $code) {
                        if (in_array($code,$checkCodeDbArr)) {
                            $checkCode[$key] = Random::alnum(8);
                        }
                    }
                    $checkCodeRes = $this->getCheckCoupons($checkCode);
                    if ($checkCodeRes['status']) {
                        $checkCode = $checkCodeRes['data'];
                    }
                }
            }
            $result['data'] = $checkCode;
        } catch (Exception $e) {
            $result['status'] = 0;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }

    /**
     * 查看是否重复-订单
     * @return void
     */
    public function getCheckOrder($checkCode=[])
    {
        $result = [
            'status' => 1,
            'msg' => '',
            'data' => [],
        ];
        try {
            if (!empty($checkCode)) {
                $where['check_code'] = ['in', $checkCode];
                $userCoupons = Db::name('order')->field('id,check_code')->where($where)->select();
                if (!empty($userCoupons)) {
                    $checkCodeDbArr = array_column($userCoupons,'check_code');
                    foreach ($checkCode as $key => $code) {
                        if (in_array($code,$checkCodeDbArr)) {
                            $checkCode[$key] = Random::alnum(8);
                        }
                    }
                    $checkCodeRes = $this->getCheckOrder($checkCode);
                    if ($checkCodeRes['status']) {
                        $checkCode = $checkCodeRes['data'];
                    }
                }
            }
            $result['data'] = $checkCode;
        } catch (Exception $e) {
            $result['status'] = 0;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }
}