<?php

namespace app\common\logic;

use app\common\enum\OrderEnum;
use app\common\enum\PayEnum;
use app\common\enum\user\UserShipEnum;
use app\common\model\dict\DictType;
use app\common\model\finance\PayNotifyLog;
use app\common\model\pay\PayNotify;
use app\common\model\store_finance_flow\StoreFinanceFlow;
use app\common\model\store_order\StoreOrder;
use app\common\model\system_store\SystemStore;
use app\common\model\user\User;
use app\common\model\user\UserAddress;
use app\common\model\user\UserRecharge;
use app\common\model\user\UserShip;
use app\common\model\user_sign\UserSign;
use app\common\service\PushService;
use support\Log;
use think\facade\Db;
use Webman\RedisQueue\Redis;

/**
 * 支付成功后处理订单状态
 * Class PayNotifyLogic
 * @package app\api\logic
 */
class PayNotifyLogic extends BaseLogic
{

    public static function handle($action, $orderSn, $extra = [], $type = 'wechat')
    {
        Db::startTrans();
        try {
            if ($action != 'cash_pay' && $action != 'balancePay' && $action != 'purchase_funds') {
                $payNotifyLogLogic = new PayNotifyLogLogic();
                if ($action == 'refund') {
                    $payNotifyLogLogic->insert($action, $extra, PayNotifyLog::TYPE_REFUND);
                } else {
                    $payNotifyLogLogic->insert($action, $extra);
                }
            }
            self::$action($orderSn, $extra, $type);
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            Log::error('支付回调处理失败' . $e->getMessage() . ',lien:' . $e->getLine() . ',file:' . $e->getFile());
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 余额支付
     * @param $orderSn
     * @param $extra
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function balancePay($orderSn, $extra = [])
    {
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();
        $user = User::where('id', $order['uid'])->find();
        if ($user['now_money'] < $order['pay_price']) {
            throw new \Exception('余额不足');
        }
        $order->money = $order['pay_price'];
        $order->paid = 1;
        $order->pay_time = time();
        if (!$order->save()) {
            throw new \Exception('订单保存出错');
        }
        // 减去余额
        $user->now_money = bcsub($user['now_money'], $order['pay_price'], 2);
        $user->save();

        $capitalFlowDao = new CapitalFlowLogic($user);
        $capitalFlowDao->userExpense('user_order_pay', 'order', $order['id'], $order['pay_price']);
        // self::afterPay($order);
        // Redis::send('push-platform-print', ['id' => $order['id']], 60);
        // PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'store_merchant', 'msg' => '您有一笔新的订单']);
    }


    /**
     * 采购款支付
     * @param $orderSn
     * @param $extra
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function purchase_funds($orderSn, $extra = [])
    {
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();
        $user = User::where('id', $order['uid'])->find();
        if ($user['purchase_funds'] < $order['pay_price']) {
            throw new \Exception('采购款不足');
        }
        $order->money = $order['pay_price'];
        $order->paid = 1;
        $order->pay_time = time();
        if (!$order->save()) {
            throw new \Exception('订单保存出错');
        }
        // 减去采购款
        $user->purchase_funds = bcsub($user['purchase_funds'], $order['pay_price'], 2);
        $user->save();

        $capitalFlowDao = new CapitalFlowLogic($user);
        $capitalFlowDao->userExpense('user_order_purchase_pay', 'order', $order['id'], $order['pay_price']);
        // self::afterPay($order);
        // Redis::send('push-platform-print', ['id' => $order['id']], 60);
        // PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'store_merchant', 'msg' => '您有一笔新的订单']);
    }

    /**
     * @notes 微信通用回调
     * @param $orderSn
     * @param array $extra
     * @date 2023/2/27 15:28
     */
    public static function wechat_common($orderSn, $extra = [])
    {
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();

        if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
            return true;
        }
        if ($order->pay_type != 10) {
            $order->pay_price = bcdiv($extra['amount']['payer_total'], 100, 2);
            $order->paid = 1;
            $order->pay_time = time();
            $order->status = 1;
            $order->save();
        } else {
            $extra['transaction_id'] = time();
        }
        $user = User::where('id', $order['uid'])->find();
        if ($order->pay_type == OrderEnum::CASHIER_ORDER_PAY || $order->pay_type == OrderEnum::CASHIER_ORDER_ALI_PAY) { //收银台支付
            $order->status = 2;
            self::afterPay($order, $extra['transaction_id']);
        } else {
            $capitalFlowDao = new CapitalFlowLogic($user);
            //微信支付和用户余额无关
            $capitalFlowDao->userExpense('user_order_pay', 'order', $order['id'], $order->pay_price, '', 1);
        }


        if ($order->pay_type == 9) {
            $extra['create_time'] = $order['create_time'];
            // PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'cash_register', 'msg' => '您有一笔订单已支付', 'data' => $extra]);
            Redis::send('push-platform-print', ['id' => $order['id']]);
        } 
        // else {
            // PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'store_merchant', 'msg' => '您有一笔新的订单']);
            //            Db::name('order_middle')->insert(['c_order_id' => $order['id']]);
        // }
        if (!empty($extra['payer']['openid']) && $order->pay_type == 7) {
            Redis::send('push-delivery', ['order_id' => $order['order_id'], 'openid' => $extra['payer']['openid']], 5);
        }
        return true;
    }

    //退款
    public static function refund($orderSn, $extra = [])
    {
        //更新状态
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();
        if ($order->isEmpty() || $order->status == OrderEnum::REFUND_PAY) {
            return true;
        }
        $order->status = OrderEnum::REFUND_PAY;
        $order->refund_status = OrderEnum::REFUND_STATUS_FINISH;
        $order->refund_price = bcdiv($extra['amount']['refund'], 100, 2);
        $order->refund_reason_time = time();
        $order->refund_num +=  1;
        $order->save();

        //        self::afterPay($order,$extra['transaction_id']);
    }

    /**
     * 充值
     */
    public static function recharge($orderSn, $extra = [], $type = 'wechat')
    {
        $order = UserRecharge::where('order_id', $orderSn)->findOrEmpty();
        if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
            return true;
        }
        if ($type == 'wechat') {
            $price =  bcdiv($extra['amount']['payer_total'], 100, 2);
        } else {
            $price = $extra['buyer_pay_amount'];
        }
        $order->price = $price;
        $order->paid = 1;
        $order->pay_time = time();
        $order->save();
        $uid = $order->uid;
        $user = User::where('id', $uid)->findOrEmpty();
        //用户的财务add
        $capitalFlowDao = new CapitalFlowLogic($user);
        $capitalFlowDao->userIncome('user_balance_recharge', 'user_recharge', $order['id'], $price);

        if ($user->isEmpty()) {
            return true;
        }
        bcscale(2);
        //        $user->now_money = bcadd($user->now_money, $price, 2);//v.1
        //更新等级
        if ($price >= 0.01) {
            $user->user_ship = 1; //v.1
        }
        $user->purchase_funds = bcadd($user->purchase_funds, $price, 2);
        $user->total_recharge_amount = bcadd($user->total_recharge_amount, $price, 2);
        $user->save();


        if (!empty($extra['payer']['openid'])) {
            Redis::send('push-delivery', ['order_id' => $order['order_id'], 'openid' => $extra['payer']['openid'], 'logistics_type' => 3], 5);
        }
        return true;
    }

    /**
     * 现金支付
     */
    public static function cash_pay($orderSn)
    {
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();

        if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
            return true;
        }
        $order->paid = 1;
        $order->pay_time = time();
        $order->status = 2;
        self::afterPay($order);
        if (!$order->save()) {
            throw new \Exception('订单保存出错');
        }
        $cashFlowLogic = new CashFlowLogic();
        $cashFlowLogic->insert($order['store_id'], $order['pay_price']);
        Redis::send('push-platform-print', ['id' => $order['id']]);
    }

    /**
     * @notes 阿里回调
     * @param $orderSn
     * @param array $extra
     * @author 段誉
     * @date 2023/2/27 15:28
     */
    public static function alipay_cashier($orderSn, $extra = [])
    {
        $order = StoreOrder::where('order_id', $orderSn)->findOrEmpty();

        if ($order->isEmpty() || $order->paid == PayEnum::ISPAID) {
            return true;
        }
        if ($order->pay_type != 10) {
            $order->money = $extra['buyer_pay_amount'];
            $order->paid = 1;
            $order->pay_time = time();
            $order->status = 1;
            $order->save();
        } else {
            $extra['transaction_id'] = time();
        }
        if ($order->pay_type == 9) {
            $order->status = 2;
            self::afterPay($order);

        }

        if ($order->pay_type == 9) {
            $extra['create_time'] = $order['create_time'];
            // PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'cash_register', 'msg' => '您有一笔订单已支付', 'data' => $extra]);
            Redis::send('push-platform-print', ['id' => $order['id']]);
        } 
        // else {
        //     PushService::push('store_merchant_' . $order['store_id'], $order['store_id'], ['type' => 'store_merchant', 'msg' => '您有一笔新的订单']);
        // }
        return true;
    }

    /**
     * 支付后逻辑
     * @param $order
     * @return void
     */
    public static function afterPay($order, $transaction_id = 0)
    {
        $financeLogic = new StoreFinanceFlowLogic();
        $financeLogic->order = $order;
        $financeLogic->user = ['uid' => $order['uid']];
        // if ($order->pay_type != 9 || $order->pay_type != 10) {
        $financeLogic->in($transaction_id, $order['pay_price'], OrderEnum::USER_ORDER_PAY);  //用户订单支付
        $count_frees = 0;
        //商户应该获得的钱 每个商品的price-ot_price 利润
        // if (isset($order->profit) && $order->profit > 0) {

        //平台手续费
        $fees = bcdiv(bcmul($order['pay_price'], '0.02', 2), 1, 2);
        $count_frees = bcadd($count_frees, $fees, 2);
        if ($fees > 0) {
            $financeLogic->in($transaction_id, $fees, OrderEnum::ORDER_HANDLING_FEES, $order['store_id'], 0, 0, $order['pay_type']);  //平台手续费
            $financeLogic->out($transaction_id, $fees, OrderEnum::ORDER_HANDLING_FEES, $order['store_id'], $order['staff_id'], 0, $order['pay_type']); //商户平台手续费支出
        }
        // $frozen = bcsub($order->profit, $fees, 2);
        //缴纳齐全了就加商户没有就加到平台
        $money_limt = SystemStore::where('id', $order['store_id'])->field('paid_deposit,security_deposit')->find();
        $deposit = bcsub($money_limt['security_deposit'], $money_limt['paid_deposit'], 2); //保证金剩余额度
        $store_profit = bcdiv(bcmul($order['pay_price'], '0.05', 2), 1, 2);
        $count_frees = bcadd($count_frees, $store_profit, 2);
        if ($deposit > 0) {
            if ($deposit > $store_profit) {
                if ($store_profit > 0) {
                    $financeLogic->out($transaction_id, $store_profit, OrderEnum::ORDER_MARGIN, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
                }
            } else {
                $money = bcsub($store_profit, $deposit, 2);
                if ($deposit > 0) {
                    $financeLogic->out($transaction_id, $deposit, OrderEnum::ORDER_MARGIN, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
                }
                if ($money) {
                    SystemStore::where('id', $order['store_id'])->inc('store_money', $money)->update();
                    $financeLogic->in($transaction_id, $money, OrderEnum::MERCHANT_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);  //平台手续费
                }
            }
        } else {
            if ($store_profit > 0) {
                SystemStore::where('id', $order['store_id'])->inc('store_money', $store_profit)->update();
                $financeLogic->in($transaction_id, $store_profit, OrderEnum::MERCHANT_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);  //平台手续费
            }
        }
        if ($order['is_vip'] >= 1) {
            if ($order['spread_uid'] > 0) {
                $financeLogic->other_arr['vip_uid'] = $order['spread_uid'];
                $fees = bcdiv(bcmul($order['pay_price'], '0.08', 2), 1, 2);
                $count_frees = bcadd($count_frees, $fees, 2);
                if ($fees > 0) {
                    User::where('id', $order['spread_uid'])->inc('now_money', $fees)->update();
                    $financeLogic->in($transaction_id, $fees, OrderEnum::VIP_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);  //vip订单获得
                    $financeLogic->out($transaction_id, $fees, OrderEnum::VIP_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
                }
            }
            $fees = bcdiv(bcmul($order['pay_price'], '0.01', 2), 1, 2);
            $count_frees = bcadd($count_frees, bcmul($fees, 3, 2), 2);
            $village_uid = 0;
            $brigade_uid = 0;
            //查询用户对应的村长和队长
            if ($order['uid'] > 0) {
                $address = UserAddress::where(['uid' => $order['uid'], 'is_default' => 1])->find();
                if ($address) {
                    $arr1 = UserAddress::where(['village' => $address['village'], 'is_default' => 1])->column('uid');
                    if ($arr1) {
                        $village_uid = User::where('id', 'in', $arr1)->where('user_ship', 2)->value('id');
                        if($village_uid){
                            User::where('id', $village_uid)->inc('integral', $fees)->update();
                        }
                    }
                    $arr2 = UserAddress::where(['village' => $address['village'], 'brigade' => $address['brigade'], 'is_default' => 1])->column('uid');
                    if ($arr2) {
                        $brigade_uid = User::where('id', 'in', $arr1)->where('user_ship', 3)->value('id');
                        if($brigade_uid){
                            User::where('id', $brigade_uid)->inc('integral', $fees)->update();
                        }
                    }
                }
            }
            if ($fees > 0) {
                //村长获得
                $sing=[];
                $user_sing=new UserSign();

                $sing[]=[
                    'uid'=>$village_uid,
                    'title'=>'村长订单获得兑换券',
                    'store_id'=>$order['store_id'],
                    'number'=>$fees,
                ];
                $sing[]=[
                    'uid'=>$brigade_uid,
                    'title'=>'队长订单获得兑换券',
                    'store_id'=>$order['store_id'],
                    'number'=>$fees,
                ];
                // if ($village_uid > 0) {
                    // $financeLogic->other_arr['vip_uid'] = $village_uid;
                // }
                // $financeLogic->in($transaction_id, $fees, OrderEnum::VILLAGE_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);
                // $financeLogic->out($transaction_id, $fees, OrderEnum::VILLAGE_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
                //队长获得
                // if ($brigade_uid > 0) {
                //     $financeLogic->other_arr['vip_uid'] = $brigade_uid;
                // }
                // $financeLogic->in($transaction_id, $fees, OrderEnum::BRIGADE_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);
                // $financeLogic->out($transaction_id, $fees, OrderEnum::BRIGADE_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
                $user_sing->saveAll($sing);
                //其他获得
                $financeLogic->other_arr['vip_uid'] = 0;
                $financeLogic->in($transaction_id, $fees, OrderEnum::OTHER_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);
                $financeLogic->out($transaction_id, $fees, OrderEnum::OTHER_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
            }
        }
        $fees=bcsub($order['pay_price'], $count_frees, 2);
        //供应链订单获得
        if ($fees > 0) {
            $financeLogic->in($transaction_id,$fees , OrderEnum::SUPPLIER_ORDER_OBTAINS, $order['store_id'], 0, 0, $order['pay_type']);
            $financeLogic->out($transaction_id, $fees, OrderEnum::SUPPLIER_ORDER_OBTAINS, $order['store_id'], $order['staff_id'], 0, $order['pay_type']);
            
        }
// }
        $financeLogic->save();
        // }
    }

    /**
     * 回调日志
     * @param $order
     * @param $extra
     * @return void
     */
    public static function notifyLog($order, $extra)
    {
        $data = [
            'pay_type' => 'wechat',
            'type' => OrderEnum::PAY,
            'amount' => $extra['amount']['payer_total'], //分
            'order_sn' => $order,
            'out_trade_no' => $extra['transaction_id'],
            'attach' => $extra['attach'],
            'create_time' => date('Y-m-d H:i:s', time()),
        ];
        PayNotify::create($data);
    }
}