<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */

namespace app\common\logic;

use app\adminapi\controller\settings\circle\Circle;
use app\common\enum\OrderEnum;
use app\common\enum\PayEnum;
use app\common\enum\UserTerminalEnum;
use app\common\enum\YesNoEnum;
use app\common\model\ArticleRewardOrder;
use app\common\model\CircleCreateOrder;
use app\common\model\MerchantTopOrder;
use app\common\model\MerchantVipOrder;
use app\common\model\Order;
use app\common\model\TwoOrder;
use app\common\model\TwoPromiseMoneyBackRequest;
use app\common\model\TwoPromiseMoneyOrder;
use app\common\model\VipOrder;
use app\common\model\PayWay;
use app\common\model\RechargeOrder;
use app\common\model\ArticleOrder;
use app\common\model\GroupOrder;
use app\common\model\CircleOrder;
use app\common\model\User;
use app\common\service\ConfigService;
use app\common\service\pay\AliPayService;
use app\common\service\pay\BalancePayService;
use app\common\service\pay\WeChatPayService;
use app\common\service\RegionService;
use think\Exception;


/**
 * 支付逻辑
 * Class PaymentLogic
 * @package app\common\logic
 */
class PaymentLogic extends BaseLogic
{
    /**
     * @notes 支付
     * @param $payWay // 支付方式
     * @param $from //订单来源(商品订单?充值订单?其他订单?)
     * @param $order //订单信息
     * @param $terminal //终端
     * @return array|bool|string|void
     * @throws \Exception
     */
    public static function pay($payWay, $from, $order, $terminal)
    {
        // pay_way 支付方式:1-余额支付;2-微信支付;3-支付宝支付
        
        //更新支付方式
        switch ($from) {
            case 'order':
                Order::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'two_order':
                // 二手商城订单
                TwoOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'vip_order':
                // vip订单
                VipOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'recharge':
                RechargeOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'article':
                ArticleOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'article_reward':
                ArticleRewardOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'two_promise_money':
                TwoPromiseMoneyOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'merchant_vip':
                MerchantVipOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'merchant_top':
                MerchantTopOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'circle':
                CircleOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'create_circle':
                \app\common\model\CircleCreateOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'pin':
                \app\common\model\PinOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'release':
                // 发布需付费
                // CircleOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                $circle = \app\common\model\Circle::find($order['circle_id']);
                $order['order_amount'] = $circle['release_price'];
                $order['sn'] = $order['id'];
                break;
            case 'group':
                // 付费进群
                GroupOrder::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'partner':
                // 搭子订单
                \app\common\model\Partner::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'merchant_goods':
                // 商家商品付费
                \app\common\model\MerchantGoodsOrder ::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
            case 'merchant_goods_package':
                // 商家团购套餐 
                \app\common\model\MerchantGoodsPackageOrder ::update(['pay_way' => $payWay], ['id' => $order['id']]);
                break;
        }

        // dd('发帖支付');
        // dd($order['order_amount']);
        // dd($order->toArray);

        if($order['order_amount'] == 0) {
            PayNotifyLogic::handle($from, $order['sn']);
            return ['pay_way'=>PayEnum::BALANCE_PAY];
        }

        // dd(PayEnum::BALANCE_PAY);
        // dd($payWay);
        switch ($payWay) {
            case PayEnum::BALANCE_PAY:
                //余额支付
                $payService = (new BalancePayService());
                $result = $payService->pay($from, $order);
                if (false !== $result) {
                    PayNotifyLogic::handle($from, $order['sn']);
                }
                break;
            case PayEnum::WECHAT_PAY:
                $payService = (new WeChatPayService($terminal, $order['user_id'] ?? null));
                // dd($payService);
                $result = $payService->pay($from, $order);
                break;
            case PayEnum::ALI_PAY:
                $payService = (new AliPayService($terminal));
                $result = $payService->pay($from, $order);
                break;
            default:
                self::$error = '订单异常';
                $result = false;
        }

        //支付成功, 执行支付回调
        if (false === $result && !self::hasError()) {
            self::setError($payService->getError());
        }
        return $result;
    }


    /**
     * @notes 获取准备预支付订单信息
     * @param $params
     * @return Order|array|false|\think\Model
     */
    public static function getPayOrderInfo($params)
    {
        try {
            switch ($params['from']) {
                case 'order':
                    $order = Order::findOrEmpty($params['order_id']);
                    if ($order->isEmpty()
                        || $order['order_status'] == OrderEnum::STATUS_CLOSE
                        || $order['delete_time'] > 0)
                    {
                        throw new \Exception('订单已关闭');
                    }
                    break;
                case 'two_order':
                    $order = TwoOrder::findOrEmpty($params['order_id']);
                    if ($order->isEmpty()
                        || $order['order_status'] == OrderEnum::STATUS_CLOSE
                        || $order['delete_time'] > 0)
                    {
                        throw new \Exception('订单已关闭');
                    }
                    break;
                case 'vip_order':
                    $order = VipOrder::findOrEmpty($params['order_id']);
                    // dd($order->toArray());
                    if ($order->isEmpty()
                        || $order['order_status'] == OrderEnum::STATUS_CLOSE
                        || $order['delete_time'] > 0)
                    {
                        throw new \Exception('订单已关闭');
                    }
                    break;
                case 'recharge':
                    $order = RechargeOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'article':
                    $order = ArticleOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'article_reward':
                    $order = ArticleRewardOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('打赏订单不存在');
                    }
                    break;
                case 'two_promise_money':
                    $order = TwoPromiseMoneyOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('保证金订单不存在');
                    }
                    break;
                case 'merchant_vip':
                    $order = MerchantVipOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('VIP订单不存在');
                    }
                    break;
                case 'merchant_top':
                    $order = MerchantTopOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('置顶订单不存在');
                    }
                    break;
                case 'group':
                    $order = GroupOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'pin':
                    $order = \app\common\model\PinOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'circle':
                    $order = CircleOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'create_circle':
                    $order = CircleCreateOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    break;
                case 'merchant_goods':
                    $order = \app\common\model\MerchantGoodsOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('商家订单不存在');
                    }
                    break;
                case 'partner':
                    $order = \app\common\model\PartnerOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('搭子订单不存在');
                    }
                    break;
                case 'release':
                    $order = \app\common\model\Article::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('充值订单不存在');
                    }
                    $order['pay_status'] = $order['release_pay'];
                    break;
                case 'blind_boxe':
                    $order = \app\common\model\BlindBoxeOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('盲盒订单不存在');
                    }
                    break;
                case 'merchant_goods_package':
                    $order = \app\common\model\MerchantGoodsPackageOrder::findOrEmpty($params['order_id']);
                    if($order->isEmpty()) {
                        throw new \Exception('优惠套餐订单不存在');
                    }
                    break;
            }
            if ($order['pay_status'] == PayEnum::ISPAID) {
                throw new \Exception('订单已支付');
            }
            return $order;
        } catch (\Exception $e) {
            self::$error = $e->getMessage();
            return false;
        }
    }


    //获取支付方式列表
    public static function getPayWay($userId, $terminal, $params)
    {
        try {
            // 获取待支付金额
            if ($params['from'] == 'order') {
                // 自营商城订单
                $order = Order::findOrEmpty($params['order_id'])->toArray();
            }else  if ($params['from'] == 'two_order') {
                // 二手商城订单
                $order = TwoOrder::findOrEmpty($params['order_id'])->toArray();
            }else  if ($params['from'] == 'vip_order') {
                // 会员升级订单
                $order = VipOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'recharge') {
                // 充值
                $order = RechargeOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'article') {
                // 付费帖子
                $order = ArticleOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'article_reward') {
                // 打赏帖子
                $order = ArticleRewardOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'two_promise_money') {
                // 保证金
                $order = TwoPromiseMoneyOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'merchant_vip') {
                // 发帖需付费
                $order = \app\common\model\MerchantVipOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'merchant_top') {
                // 发帖需付费
                $order = \app\common\model\MerchantTopOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'release') {
                // 发帖需付费
                $order = \app\common\model\Article::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'group') {
                // 进群需付费
                $order = GroupOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'group') {
                // 付费圈子
                $order = CircleOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'pin') {
                // 付费推广
                $order = \app\common\model\PinOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'circle') {
                // 付费创建圈子
                $order = CircleOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'create_circle') {
                // 付费创建圈子
                $order = \app\common\model\CircleCreateOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'merchant_goods') {
                // 商家商品付费
                $order = \app\common\model\MerchantGoodsOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'partner') {
                // 搭子订单
                $order = \app\common\model\PartnerOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'blind_boxe') {
                // 盲盒交友
                $order = \app\common\model\BlindBoxeOrder::findOrEmpty($params['order_id'])->toArray();
            }else if ($params['from'] == 'merchant_goods_package') {
                // 优惠套餐
                $order = \app\common\model\MerchantGoodsPackageOrder::findOrEmpty($params['order_id'])->toArray();
            }else if (empty($order) || !isset($order)) {
                throw new \Exception('待支付订单不存在');
            }

            // 获取订单剩余支付时间
            $cancelUnpaidOrders = ConfigService::get('transaction', 'cancel_unpaid_orders');
            $cancelUnpaidOrdersTimes = ConfigService::get('transaction', 'cancel_unpaid_orders_times');

            if (empty($cancelUnpaidOrders) ) {
                // 不自动取消待支付订单
                $cancelTime = 0;
            } else {
                // 指定时间内取消待支付订单
                $cancelTime = strtotime($order['create_time']) + intval($cancelUnpaidOrdersTimes) * 60;
            }
            
            //获取支付场景
            $scene = UserTerminalEnum::trueerminalEnumByScene($params['scene']);
            $pay_way = PayWay::alias('pw')
                ->join('dev_pay dp', 'pw.dev_pay_id = dp.id')
                ->where(['pw.scene'=>$scene,'pw.status'=>YesNoEnum::YES])
                ->field('dp.id,dp.name,dp.pay_way,dp.icon,dp.sort,dp.remark')
                ->order('pw.is_default desc,dp.sort desc,id asc')
                ->select()
                ->toArray();
            foreach ($pay_way as $k=>&$item) {

                // 仅支持余额支付
                if($item['pay_way'] == PayEnum::WECHAT_PAY ||
                $item['pay_way'] == PayEnum::ALI_PAY ){
                    $a=['recharge','order','two_order'];
                    if(!in_array($params['from'],$a)){
                        unset($pay_way[$k]);
                    }
                }
                

                if ($item['pay_way'] == PayEnum::WECHAT_PAY) {
                    $item['extra'] = '微信快捷支付';
                }

                if ($item['pay_way'] == PayEnum::ALI_PAY) {
                    $item['extra'] = '支付宝快捷支付';
                }

                if ($item['pay_way'] == PayEnum::BALANCE_PAY) {
                    $user_money = User::where(['id' => $userId])->value('user_money');
                    $item['extra'] = '可用余额:'.$user_money;
                }
                // 充值时去除余额支付
                if ($params['from'] == 'recharge' && $item['pay_way'] == PayEnum::BALANCE_PAY) {
                    unset($pay_way[$k]);
                }

                // 帖子付费 仅余额支付
                // if ($params['from'] == 'article' && (
                //         $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //         $item['pay_way'] == PayEnum::ALI_PAY 
                //     )) {
                //     // 付费帖子
                //     unset($pay_way[$k]);
                // }

                // 群付费 仅余额支付
                // if ($params['from'] == 'group' && (
                //         $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //         $item['pay_way'] == PayEnum::ALI_PAY 
                //     )) {
                //     // 付费帖子
                //     unset($pay_way[$k]);
                // }

                // 付费推广 仅余额支付
                // if ($params['from'] == 'pin' && (
                //         $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //         $item['pay_way'] == PayEnum::ALI_PAY 
                //     )) {
                //     // 付费帖子
                //     unset($pay_way[$k]);
                // }

                // 发帖付费 仅余额支付
                // if ($params['from'] == 'release' && (
                //     $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //     $item['pay_way'] == PayEnum::ALI_PAY 
                // )) {
                //     // 付费帖子
                //     unset($pay_way[$k]);
                // }
                // if($params['from'] == 'release'){
                //     // dd($order['circle_id']);
                //     $circle = \app\common\model\Circle::find($order['circle_id'])->toArray();
                //     $order['order_amount'] = $circle['release_price'];
                // }

                // 圈子付费 仅余额支付
                // if ($params['from'] == 'circle' && (
                //     $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //     $item['pay_way'] == PayEnum::ALI_PAY 
                // )) {
                //     // 付费帖子
                //     unset($pay_way[$k]);
                // }

                // 会员付费 仅余额支付
                // if ($params['from'] == 'vip_order' && (
                //     $item['pay_way'] == PayEnum::WECHAT_PAY ||
                //     $item['pay_way'] == PayEnum::ALI_PAY 
                // )) {
                //     // 付费vip
                //     unset($pay_way[$k]);
                // }
            }

            return [
                'lists' => array_values($pay_way),
                'order_amount' => $order['order_amount'],
                'cancel_time' => $cancelTime,
            ];
        } catch (\Exception $e) {
            self::setError($e->getMessage());
            return false;
        }
    }

    /**
     * @notes 查看订单支付状态
     * @param $params
     * @return array|false
     */
    public static function getPayStatus($params)
    {
        try {
            if ($params['from'] == 'order') {
                $order = Order::with('orderGoods')->findOrEmpty($params['order_id']);
                $payStatus = $order->pay_status;
                $orderInfo = '';
            } else if ($params['from'] == 'two_order') {
                $order = TwoOrder::with('orderGoods')->findOrEmpty($params['order_id']);
                $payStatus = $order->pay_status;
                $orderInfo = '';
            } else if ($params['from'] == 'recharge') {
                $order = RechargeOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 充值无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'article') {
                $order = ArticleOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'article_reward') {
                $order = ArticleRewardOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'two_promise_money') {
                $order = TwoPromiseMoneyOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'merchant_vip') {
                $order = MerchantVipOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'merchant_top') {
                $order = MerchantTopOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            } else if ($params['from'] == 'circle') {
                $order = CircleOrder::findOrEmpty($params['order_id']);
                $orderInfo = ''; // 无需返回订单详情
                $payStatus =  $order->getData('pay_status');
            }
            if ($order->isEmpty()) {
                throw new \Exception('订单不存在');
            }
            return [
                'pay_status' => $payStatus,
                'pay_way' => $order->pay_way,
                'order' => $orderInfo
            ];
        } catch (\Exception $e) {
            self::setError($e->getMessage());
            return false;
        }
    }





    /**
     * @notes 获取支付结果
     * @param $params
     * @return array
     * @date 2022/4/6 15:23
     */
    public static function getPayResult($params)
    {
        switch ($params['from']) {
            case 'order' :
                $result = Order::where(['id' => $params['order_id']])
                    ->field(['id', 'sn', 'pay_time', 'pay_way', 'order_amount', 'pay_status'])
                    ->findOrEmpty()
                    ->toArray();
                $result['total_amount'] = '￥' . $result['order_amount'];
                break;
            default :
                $result = [];
        }

        if (empty($result)) {
            self::$error = '订单信息不存在';
        }

        $result['pay_way'] = PayEnum::getPayDesc($result['pay_way']);
        return $result;
    }

}