<?php
/**
 * 支付接口控制器
 */
namespace app\modules\shops\v1\controllers;
use app\modules\common\Helper;
use app\modules\common\Verify;
use app\modules\logic\services\UserService;
use app\modules\logic\services\AccountService;
use app\modules\logic\services\OrderService;
use app\modules\logic\services\CouponService;
use app\modules\logic\model\OrderModel;
use app\modules\logic\model\PayLogModel;
use Yii;
use yii\web\Controller;
use app\modules\third\payment\Wxpay;
use app\modules\third\payment\H5pay;
class PayController extends MiddleController {
	/**
	 * 返回
	 * @param $code
	 * @param string $info
	 * @param string $controller
	 * @param string $total
	 */
	protected function response($code, $info = '', $total = '', $controller = 'pay') {
		return parent::response($code, $info, $total, $controller);
	}
	/**
	 * [actionPayorder 发起支付]
	 * @apiDoc
	 * @api     v1/pay/payorder
	 * @group   pay
	 * @name    发起支付
	 * @desc    门店APP-发起订单-支付
	 * @method  POST
	 * @param order_type int 支付类型[1,订单,2,购买精誉币,3,支付违约金] req
	 * @param pay_way int 支付方式[1,微信,2,精誉币,3信用额度/挂账] req
	 * @param order_id int 订单ID[支付订单必填] noreq
	 * @param cid int 优惠券ID noreq
	 * @param money int 金额【购买金额】 noreq
	 * @author JOHN.W
	 * @version [1.0]
	 * @return  json
		{
		"code": "000000",
		"msg": "支付成功",
		"info": "1"
		}
	 */
	public function actionPayorder(){
		if (empty($this->user_id)) {
            return $this->response('para_miss_user', '未能识别用户标志');
        }
        if(empty($this->para['order_type'])){
        	return $this->response('para_miss', '支付类型不能为空');
        }
        $ret = ['msg'=>'支付失败#000'];

        switch ($this->para['order_type']) {
        	case '1':
        		if(empty($this->para['order_id'])){
        			return $this->response('para_miss', '订单ID不能为空');
        		}
        		$order_id = $this->para['order_id'];
        		if(empty($this->para['pay_way']) || !in_array($this->para['pay_way'], ['1','2','3'])){
        			return $this->response('para_miss', '支付方式不存在');
        		}
        		$order_info = self::getPrice($order_id);
        		if(!isset($order_info) || $order_info['status']!=0){
        			return $this->response('para_miss', '订单异常#STAFL');
        		}
        		//优惠券
        		$cid = !empty($this->para['cid'])?$this->para['cid']:0;
        		//获取优惠金额
        		$order_info['offer_money'] = $order_info['cou_money'];//优惠金额
        		$order_info['extra'] = json_encode(['cid'=>$cid]);
        		$order_info['sp_user_id'] = $this->user_id;
        		$order_info['order_type'] = $this->para['order_type'];

        		switch ($this->para['pay_way']) {
        			case '1':
        				$ret = $this->payByWx($order_info);
						if(isset($ret['status']) && $ret['status']==1){
							return $this->response('deal_succ', '下单成功',$ret['data']);
						}else{
							return $this->response('deal_false', $ret['msg']);
						}
        				break;
        			case '2':
        				$ret = $this->payByGold($order_info);
        				break;
        			case '3':
        				$ret = $this->payByCredit($order_info);
        				break;	
        		}
        		//如果支付成功有优惠券的情况，使用优惠券
        		if(!empty($cid) && (isset($ret['status']) && $ret['status']==1)){
        			CouponService::useCou(['id'=>$cid,'use_order_id'=>$order_id,'use_uid'=>$this->user_id]);
        		}
        		break;
        	case '2':
        		if(empty($this->para['money']) || !is_numeric($this->para['money'])){
        			return $this->response('para_miss', '购买金额错误');
        		}
        		$buy_money = $this->para['money'];
        		$order_info = [];
        		$order_info['price'] = $buy_money;
        		$order_info['offer_money'] = 0;
        		$order_info['nid'] = Helper::getOrderNid("BCN");
        		$order_info['order_id'] = 0;
        		$order_info['extra'] = json_encode($this->para);
        		$order_info['sp_user_id'] = $this->user_id;
        		$order_info['order_type'] = $this->para['order_type'];
				$ret = $this->payByWx($order_info);
				if(isset($ret['status']) && $ret['status']==1){
					return $this->response('deal_succ', '下单成功',$ret['data']);
				}else{
					return $this->response('deal_false', $ret['msg']);
				}
        		break;
        	case '3':
        		if(empty($this->para['money']) || !is_numeric($this->para['money'])){
        			return $this->response('para_miss', '违约金金额错误');
        		}
        		if(empty($this->para['order_id'])){
        			return $this->response('para_miss', '订单ID不能为空');
        		}
        		$buy_money = $this->para['money'];
        		$order_info = [];
        		$order_info['price'] = $buy_money;
        		$order_info['offer_money'] = 0;
        		$order_info['nid'] = Helper::getOrderNid("PCM");
        		$order_info['order_id'] = $this->para['order_id'];
        		$order_info['extra'] = json_encode($this->para);
        		$order_info['sp_user_id'] = $this->user_id;
        		$order_info['order_type'] = $this->para['order_type'];
				$ret = $this->payByWx($order_info);
				if(isset($ret['status']) && $ret['status']==1){
					return $this->response('deal_succ', '下单成功',$ret['data']);
				}else{
					return $this->response('deal_false', $ret['msg']);
				}
        		break;	
        	default:
        		return $this->response('para_miss', '支付类型不存在');
        }
        if(isset($ret['status']) && $ret['status']==1){
        	return $this->response('deal_succ', '支付成功',$order_id);
        }else{
        	return $this->response('deal_false', $ret['msg']);
        }

	}
	/*币支付订单*/
	private function payByGold($param = []){
		//查询账户金币是否足够
		$account = AccountService::getAccount($param['shop_user_id']);
		if(!isset($account['account']['total_gold']) || $account['account']['total_gold']<$param['price']){
			return ['status'=>0,'msg'=>'余额不足'];
		}
		//减去优惠金额
		$param['price'] = ($param['price']-$param['offer_money'])>0?$param['price']-$param['offer_money']:0;
		$data = [
			'user_id'=>$account['account']['user_id'],
			'nid'=>$param['nid'],
			'money'=> -1*$param['price'],
			'money_type'=>'gold',
			'op_type'=>'pay_order',
			'remark'=>'支付订单'
		];
		$res = AccountService::addAccountLog($data);
		if($res){
			//成功后添加支付记录
			$pay_log = [
				'nid'=>$param['nid'],
				'sp_user_id'=>$param['sp_user_id'],
				'user_id'=>$data['user_id'],
				'order_id'=>$param['order_id'],
				'offer_money'=>$param['offer_money'],
				'pay_money'=>$param['price'],
				'pay_way'=>2,
				'extra'=>$param['extra'],
				'status'=>1,
			];
			self::addPayLog($pay_log);
			OrderService::upOrderPaySuc($param['order_id']);
			return ['status'=>1,'msg'=>'支付成功'];
		}else{
			return ['status'=>0,'msg'=>'支付失败'];
		}
	}
	/*发起微信支付订单*/
	private function payByWx($param = []){
		//减去优惠金额
		$param['price'] = ($param['price']-$param['offer_money'])>0?$param['price']-$param['offer_money']:0;
		//微信下单前端缓存
		$pay_cache = Helper::getPayLog([
			'user_id' => $param['sp_user_id'],
			'order_type' => $param['order_type'],
			'pay_way' => 1,
			'pay_money'=>$param['price'],
			'order_id' => $param['order_id']
		]);

		if (!empty($pay_cache)) {
			return ['status'=>1,'msg'=>'下单成功','data'=>$pay_cache];
		}
		//微信下单前端缓存 --end
		$data_pay = [
			'order_nid' => $param['nid'],
			'money' => $param['price'],
			'terminalType' =>Yii::$app->frontParam->getData('terminalType'),
			'body' => Helper::payToAccountRemark($param['order_type']),
			'user_id' => $param['sp_user_id'],
		];

		//微信端下单
		$version = empty(Yii::$app->frontParam->getData('version')) ? 0 : Yii::$app->frontParam->getData('version');
		$pay = new Wxpay($version);
		$result = $pay->unifiedOrder($data_pay);

		$pay_log = [
			'nid'=>$param['nid'],
			'sp_user_id'=>$param['sp_user_id'],
			'user_id'=>$param['sp_user_id'],
			'order_id'=>$param['order_id'],
			'offer_money'=>$param['offer_money'],
			'pay_money'=>$param['price'],
			'order_type'=>$param['order_type'],
			'pay_way'=>1,
			'extra'=>$param['extra'],
		];
		if ($result['code'] == 1) {
			$pay_log['prepay_id'] = $result['prepay_id']; //微信生成的预支付回话标识，用于后续接口调用中使用
			$pay_log['status'] = 0;
		} else {
			$pay_log['status'] = 2;
			$pay_log['note'] = $result['msg'];
		}

		$sv_res = self::addPayLog($pay_log);//保存支付日志
		if (!$sv_res) {
			return ['status'=>0,'msg'=>'下单失败请重试','data'=>$sv_res];
		}
		if ($result['code'] == 1) {
			/*if ($this->para['terminalType'] == 'android') {
				$result['data']['safe_url'] = Yii::$app->params['wxpay']['h5_safe_url']['android'];
			} else {
				$result['data']['safe_url'] = Yii::$app->params['wxpay']['h5_safe_url']['ios'];
			}*/
			//支付缓存
			Helper::setPayLog([
				'user_id' => $param['sp_user_id'],
				'order_type' => $param['order_type'],
				'pay_way' => 1,
				'pay_money'=>$param['price'],
				'order_id' => $param['order_id']
			], $result['data']);
			return ['status'=>1,'msg'=>'下单成功','data'=>$result['data']];
		} else {
			Yii::warning('统一下单失败:user_id:' .$param['sp_user_id'] . ' ' . $result['msg']);
			return ['status'=>0,'msg'=>'下单失败'.$result['msg']];
		}
	}
	/**
	 * [actionNotify 使用微信支付后通知]
	 * @apiDoc
	 * @api    v1/pay/notify
	 * @group  pay
	 * @name   支付完成后回调
	 * @desc   是否完成后回调通知
	 * @method POST
	 * @param nid string 订单号 req
	 * @return json
		{
		"code": "000000",
		"msg": "支付成功",
			"info": {
				"status_name": "成功",
				"resultCode": "1"
			}
		}
	 */
	public function actionNotify(){
		if (empty($this->user_id)) {
            return $this->response('para_miss_user', '未能识别用户标志');
        }
        if (!isset($this->para['nid']) || empty($this->para['nid'])) {
            return $this->response('para_miss', '请输入查询订单号');
        }
        $PayLog = new PayLogModel();
        $row = $PayLog->find()->where(['nid'=>$this->para['nid']])->asArray()->one();

        if(!isset($row) || $row['pay_way']!=1){
        	return $this->response('deal_false', '订单获取失败');
        }
        
        //已经处理完-直接返回成功
		if (isset($row['status']) && $row['status'] == 1) {
		    return $this->response('deal_succ', '支付成功', [
		        'status_name' => '成功',//responseMessage
		        'resultCode' => Helper::orderStatusByJh('S'),
		    ]);
		}
        //请求订单状态
        $version = empty($this->para['version']) ? 0 : $this->para['version'];
        $pay = new Wxpay($version);
        $response_data = $pay->status(['nid' => $row['nid']]);

        if ($response_data['return_code'] == 'SUCCESS' && $row['status']==0) {
            if ($response_data['result_code'] == 'SUCCESS' and $response_data['trade_state'] == 'SUCCESS') {
                //微信支付成功  生成订单
                $money = $response_data['total_fee'] / 100.0;
                $data_update = [
                	'transaction_id'=>$response_data['transaction_id'],
                    'status' => 1,
                    'notify_time' => time(),
                    'notice' => '支付成功',
                ];
                //支付成功创建响应逻辑
                AccountService::updatePayLog($data_update, $row['id']);
                return $this->response('deal_succ', '支付成功', [
                    'status_name' => '成功',//responseMessage
                    'resultCode' => Helper::orderStatusByJh('S'),
                ]);
            } else {
                return $this->response('deal_succ', $response_data['trade_state_desc'], [
                    'status_name' => $response_data['trade_state_desc'],//responseMessage
                    'resultCode' => Helper::orderStatusByJh('F'),
                ]);
            }
        } else {

            return $this->response('deal_false', '订单获取失败');
        }
	}



	/*挂账支付*/
	private function payByCredit($param = []){
		$account = AccountService::getAccount($param['shop_user_id']);
		if(!isset($account['credit']['use_amount']) || $account['credit']['use_amount']<$param['price']){
			return ['status'=>0,'msg'=>'挂账额度不足'];
		}
		//减去优惠金额
		$param['price'] = ($param['price']-$param['offer_money'])>0?$param['price']-$param['offer_money']:0;
		$data = [
			'user_id'=>$account['account']['user_id'],
			'nid'=>$param['nid'],
			'money'=> -1*$param['price'],
			'money_type'=>'money',
			'op_type'=>'pay_order',
			'remark'=>'支付订单'
		];
		$res = AccountService::addAccountLog($data);
		if($res){
			//成功后添加支付记录
			$pay_log = [
				'nid'=>$param['nid'],
				'sp_user_id'=>$param['sp_user_id'],
				'user_id'=>$data['user_id'],
				'order_id'=>$param['order_id'],
				'offer_money'=>$param['offer_money'],
				'pay_money'=>$param['price'],
				'pay_way'=>3,
				'extra'=>$param['extra'],
				'status'=>1,
			];
			self::addPayLog($pay_log);
			OrderService::upOrderPaySuc($param['order_id']);
			return ['status'=>1,'msg'=>'支付成功'];
		}else{
			return ['status'=>0,'msg'=>'支付失败'];
		}
	}
	/*获取订单价格以及状态*/
	private function getPrice($order_id  = 0){
		$Order = new OrderModel();
		$row = $Order->getWidgetRow(['cols'=>['price','status','shop_user_id','order_id','nid','cou_money'],'order_id'=>$order_id]);
		return $row;
	}
	/**
	 * [addPayLog 添加支付记录]
	 */
	private function addPayLog($param = []){
		$pay_log = [
			'sp_user_id'=>$param['sp_user_id'],
			'order_id'=>$param['order_id'],
			'offer_money'=>$param['offer_money'],
			'pay_money'=>$param['pay_money'],
			'user_id'=>$param['user_id'],
			'order_type'=>isset($param['order_type'])?$param['order_type']:1,
			'pay_way'=>$param['pay_way'],
			'nid'=>$param['nid'],
			'extra'=>isset($param['extra'])?$param['extra']:'',
			'status'=>$param['status'],
			'created'=>time(),
		];
		$PayLog = new PayLogModel();
		return $PayLog->saveUs($pay_log);
	}

}