<?php

namespace App\Models;

use App\Command\Log;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\DB;
use App\Models\Good as GoodModel;
use App\Models\GoodSku;
use NwVVVS\AdapayCore\AdaPay\Payment;

class Adapay
{
    public const APP_ID = 'app_c383f483-3c2a-41b6-8d21-7f597dde4c50';

    public function __construct()
    {
        /**
         * 商户接入AdaPay SDK时需要设置的初始化参数
         * 设置配置从配置文件读取
         */
        \NwVVVS\AdapayCore\AdaPay::init(dirname(__FILE__) . "/../../config/merchantConfig.json", "test");
    }


    public function pay($order_title, $order_sn, $order_amount, $openid)
    {
        $payment = new \NwVVVS\AdapaySdk\Payment();

        # 支付设置
        $payment_params = [
            "app_id" => Adapay::APP_ID,
            "order_no" => $order_sn,
            "pay_channel" => "wx_lite",
            "pay_mode" => "delay",
            "time_expire" => date('YmdHis', time() + 300),
            "pay_amt" => "0.01",
            "goods_title" => $order_title,
            "goods_desc" => $order_title,
            "description" => "",
            "notify_url" => env('API_URL') . '/pay-notify',
            "expend" => [
                "open_id" => $openid
            ]
        ];

        # 发起支付
        $payment->create($payment_params);

        # 对支付结果进行处理
        Log::add('--调起支付--', $payment->result);
        if ($payment->isError()) {
            //失败处理
            throw new \Exception($payment->result['error_msg']);
        } else {
            //成功处理
            Log::add('--支付参数--', json_decode($payment->result['expend']['pay_info'], true));
            $item = json_decode($payment->result['expend']['pay_info'], true);
            $item['timestamp'] = $item['timeStamp'];
            return $item;
        }
    }

    public function payNotify($params = [])
    {
        $payment_confirm = new \NwVVVS\AdapaySdk\PaymentConfirm(); //支付确认
        $adapay_tools = new \NwVVVS\AdapaySdk\AdapayTools(); //验证签名
        $post_data = json_decode($params['data'], 1);
        $post_data_str = json_encode($post_data, JSON_UNESCAPED_UNICODE);
        $post_sign_str = isset($params['sign']) ? $params['sign'] : '';
        # 先校验签名和返回的数据的签名的数据是否一致
        $sign_flag = $adapay_tools->verifySign($post_data_str, $post_sign_str);

        if (!$sign_flag) {
            Log::add('支付签名验证失败', []);
            return false;
        }
        $message = $post_data;
        $order_no = $message['order_no'];
        $orderObj = OrderInfo::where(['order_sn' => $order_no])->first();
        if (!$orderObj) {
            Log::add('订单不存在', [$order_no]);
            return false;
        }
        //支付完成后通知
        if ($message['status'] == "succeeded" && $orderObj->pay_status == 0) {
            DB::beginTransaction();
            try {
                //更新订单
                if ($orderObj->pay_status == 0) {
                    $orderObj->order_status = 1;
                    $orderObj->pay_status = 1;
                    $orderObj->freeze_stat = $message['freeze_stat'];
                    if ($orderObj->save()) {
                        //更新商品销量、库存
                        $goodsList = OrderGoods::where("order_id", $orderObj->id)->get();
                        foreach ($goodsList as $item) {
                            //Log::add('--订单商品对象--', $item);
                            $gid = $item->goods_id;
                            $attr_id = $item->attr_id;
                            $mer_id = $item->merchant_id;
                            $goods_number = $item->goods_number;
                            //更新此商品支付状态
                            $item->is_pay = 1;
                            $item->save();

                            $goodsObj = GoodModel::find($gid);
                            //更新商品规格库存
                            $attrObj = GoodSku::find($attr_id);
                            $attr_stock = ($attrObj->stock - $goods_number) >= 0 ? $attrObj->stock - $goods_number : 0;
                            $attrObj->stock = $attr_stock;
                            $attrObj->save();
                            //更新商品sku
                            $skuArr = json_decode($goodsObj->sku, true);
                            if ($skuArr['sku']) {
                                foreach ($skuArr['sku'] as $kk => $vv) {
                                    if (isset($vv['attr_sn']) && $vv['attr_sn'] == $attrObj->attr_sn) {
                                        $skuArr['sku'][$kk]['stock'] = $attr_stock;
                                    }
                                }
                                $goodsObj->sku = json_encode($skuArr, JSON_UNESCAPED_UNICODE);
                                $goodsObj->save();
                            }
                            //商户规格库存
                            $mgsObj = MerchantGoodSku::where(['goods_id' => $gid, 'attr_id' => $attr_id, 'merchant_id' => $mer_id])->first();
                            if ($mer_id && $mgsObj) {
                                $changeStock = ($mgsObj->stock >= $goods_number) ? $mgsObj->stock - $goods_number : 0;
                                $mgsObj->stock = $changeStock;
                                $mgsObj->save();
                            }
                        }
                    }
                }
                //支付记录
                $pay_cord = new PaymentRecord();
                $cordLog = $pay_cord->where(['order_sn' => $message['order_no']])->first();
                if (!$cordLog) {
                    $pay_cord->order_sn = $message['order_no'];
                    $pay_cord->other_order = $message['out_trans_id'];
                    $pay_cord->payment_id = $message['id'];
                    $pay_cord->party_order_id = $message['party_order_id'];
                    $pay_cord->money = $message['real_amt'];
                    $pay_cord->uid = $orderObj->user_id;
                    $pay_cord->save();
                }
                DB::commit();
            } catch (\Exception $e) {
                Log::add('付款回调失败', $e);
                DB::rollBack();
                return false;
            }
        }
        //解冻通知
        $freeze_stat = $message['freeze_stat'] ?? '';
        if ($message['status'] == "succeeded" && $orderObj->freeze_stat == 'FREEZE') {
            if ($freeze_stat != 'UNFREEZE') {
                return false;
            }
            //交易记录
            $prObj = PaymentRecord::where('order_sn', $order_no)->first();
            # 支付确认参数设置
            $payment_params = array(
                "payment_id" => $prObj->payment_id,
                "order_no" => 'payconfirm_' . date("YmdHis") . rand(100000, 999999),
                "confirm_amt" => $prObj->money,
                "description" => "",
                "div_members" => "" //分账参数列表 默认是数组List
            );
            //分账列表
            $payment_params['div_members'] = OrderDivideRecord::divide($orderObj->id); //返回分账参数列表

            Log::add('发起支付确认' . $order_no, $payment_params);
            DB::beginTransaction();
            try {
                # 发起支付确认创建
                $payment_confirm->create($payment_params);
                # 对支付确认创建结果进行处理
                if ($payment_confirm->isError()) {
                    //失败处理
                    Log::add('支付确认失败', $payment_confirm->result);
                    $result = $payment_confirm->result;
                } else {
                    //成功处理
                    Log::add('支付确认成功', $payment_confirm->result);
                    $result = $payment_confirm->result;
                    if ($result['status'] == 'succeeded') {
                        $orderObj->freeze_stat = 'UNFREEZE';
                        $orderObj->save();
                    }
                }

                DB::commit();
            } catch (\Exception $e) {
                Log::add('支付确认对象失败', $e);
                DB::rollBack();
                return false;
            }
        }
        return  true;
    }

    //创建支付确认
    public function createPaymentConfirm($payment_params)
    {
        $payment = new \NwVVVS\AdapaySdk\PaymentConfirm();

        # 发起支付确认创建
        $payment->create($payment_params);

        # 对支付确认创建结果进行处理
        if ($payment->isError()) {
            //失败处理
            Log::add('支付确认返回结果,失败', $payment->result);
            echo "<pre>";
            print_r($payment->result);
        } else {
            //成功处理
            echo "<pre>";
            Log::add('支付确认返回结果,成功', $payment->result);
            print_r($payment->result);
        }
    }

    //查询支付对象列表
    public function queryList($payment_params)
    {
        $payment = new \NwVVVS\AdapaySdk\Payment();

        $payment->queryList($payment_params);
        # 对支付结果进行处理
        if ($payment->isError()) {
            //失败处理
            echo "<pre>";
            print_r($payment->result);
        } else {
            //成功处理
            echo "<pre>";
            print_r($payment->result);
            die;
        }
    }

    //退款
    public function refund($order_sn, $refund_no)
    {
        #初始化退款对象
        $payment = new \NwVVVS\AdapaySdk\PaymentReverse();

        $payLog = PaymentRecord::where('order_sn', $order_sn)->first();

        $payment_params = array(
            # 支付对象ID
            "payment_id" => $payLog->payment_id,
            # 商户app_id
            "app_id" => Adapay::APP_ID,
            # 撤销订单号
            "order_no" => $refund_no,
            # 撤销金额
            "reverse_amt" => $payLog->money,
            # 通知地址
            "notify_url" => env('API_URL') . '/refund-notify',
            # 撤销原因
            "reason" => "取消订单",
            # 扩展域
            "expand" => "",
            # 设备信息
            "device_info" => "",
        );
        # 发起支付撤销
        $payment->create($payment_params);
        # 对支付撤销结果进行处理
        if ($payment->isError()) {
            //失败处理
            Log::add('撤销失败', $payment->result);
            $msg = isset($payment->result['error_msg']) ? $payment->result['error_msg'] : '撤销失败';
            throw new \Exception($msg);
        }
        $result = $payment->result;
        Log::add('撤销成功', $result);

        //系统订单信息
        $orderObj = OrderInfo::where("order_sn", $order_sn)->first();

        //退款记录
        $refund_cord = new RefundRecord();
        $cordLog = $refund_cord->where(['refund_no' => $result['order_no']])->first();
        if (!$cordLog) {
            $refund_cord->order_sn = $order_sn;
            $refund_cord->refund_no = $result['order_no'];
            $refund_cord->payment_id = $result['id'];
            $refund_cord->money = $result['reverse_amt'];
            $refund_cord->uid = $orderObj->user_id;
            $refund_cord->save();
        }
        return true;
    }

    //退款回调
    public function refundNotify($params)
    {
        $adapay_tools = new \NwVVVS\AdapaySdk\AdapayTools();
        $post_data = json_decode($params['data'], 1);
        $post_data_str = json_encode($post_data, JSON_UNESCAPED_UNICODE);
        $post_sign_str = isset($params['sign']) ? $params['sign'] : '';
        # 先校验签名和返回的数据的签名的数据是否一致
        $sign_flag = $adapay_tools->verifySign($post_data_str, $post_sign_str);

        if (!$sign_flag) {
            //Log::add('退款签名验证失败', []);
            //return false;
        }
        $message = $post_data;
        $recordObj = RefundRecord::where(['refund_no' => $message['order_no'], 'payment_id' => $message['id']])->first();
        if (!$recordObj) {
            Log::add('退单记录不存在', [$message['order_no']]);
            return false;
        }
        if ($message['status'] == 'succeeded') {
            $recordObj->status = 1;
            $recordObj->save();
            return true;
        }
        return false;
    }


    //创建个人用户
    public function createMember($uid, $phone)
    {
        $member = new \NwVVVS\AdapaySdk\Member();
        $member_params = array(
            # app_id
            "app_id" => Adapay::APP_ID,
            # 用户id
            "member_id" => "mm_" . $uid,
            # 用户手机号
            "tel_no" => $phone,
        );
        # 创建
        $member->create($member_params);

        # 对创建用户对象结果进行处理
        if ($member->isError()) {
            //失败处理
            Log::add('创建用户失败-' . $uid, $member->result);
            return $member->result;
        } else {
            //成功处理
            Log::add('创建用户成功', $member->result);
            return $member->result;
        }
    }
    //创建企业用户
    public function createCompany($member_params)
    {

        $member = new \NwVVVS\AdapaySdk\CorpMember();

        # 创建企业用户
        $member->create($member_params);
        # 对创建企业用户结果进行处理
        if ($member->isError()) {
            //失败处理
            return $member->result;
        } else {
            //成功处理
            return $member->result;
        }
    }

    //创建结算对象
    public function createMemberSettleAccount($account_params)
    {
        $account = new \NwVVVS\AdapaySdk\SettleAccount();

        # 创建结算账户
        $account->create($account_params);
        # 对创建结算账户结果进行处理
        if ($account->isError()) {
            //失败处理
            Log::add('创建用户结算账户失败', $account->result);
            return $account->result;
        } else {
            //成功处理
            Log::add('创建用户结算账户成功', $account->result);
            return $account->result;
        }
    }


    //删除结算账户
    public function deleteSettleAccount($account_params)
    {
        $account = new \NwVVVS\AdapaySdk\SettleAccount();

        # 结算账户
        $account->delete($account_params);

        # 对删除结算账户结果进行处理
        if ($account->isError()) {
            //失败处理
            return $account->result;
        } else {
            //成功处理
            return $account->result;
        }
    }
}