<?php

namespace app\common\service\order;

use think\facade\Db;
use app\common\exception\BaseException;
use app\common\model\order\Order as OrderModel;
use app\common\model\order\OrderGoods as OrderGoodsModel;
use app\common\model\order\OrderRefunds as OrderRefundsModel;
use app\common\model\Users as UsersModel;
use app\common\model\users\UsersLog as UsersLogModel;
use app\common\model\users\UsersPointLog as UsersPointLogModel;
use app\common\model\Payment as PaymentModel;
use app\common\library\payment\Alipay as AlipayPayment;
use app\common\library\payment\Wechat as WechatPayment;

/**
 * @package app\common\service\order
 * @class Order
 * @author xzncit 2024/3/19
 */
class Order {

    public static function delivery($id){
        try{
            OrderModel::startTrans();
            $order = OrderModel::where("id",$id)->find();

            if(empty($order)){
                throw new BaseException("您要查找的订单不存在",0);
            }

            if(!in_array($order["status"],[4,5])){
                throw new BaseException("该订单不允许执行此操作",0);
            }

            OrderModel::where("id",$order["id"])->save([
                "status"=>6,
                "collect_status"=>2,
                "accept_time"=>time(),
                "completion_time"=>time()
            ]);

            if($order["point"] > 0){
                UsersModel::where("id",$order["user_id"])->save([
                    "score"=>Db::raw("score+" . $order["point"])
                ]);

                UsersPointLogModel::create([
                    "user_id"       => $order["user_id"],
                    "type"          => 1,
                    "value"         => $order["point"],
                    "content"       => "订单返现",
                    "create_time"   => time()
                ]);
            }

            OrderModel::commit();
            return true;
        }catch (\Exception $ex){
            OrderModel::rollback();
            throw new $ex;
        }
    }

    /**
     * @param string|int $id
     * @param string|int $type 1:直接退款 2:审核退款
     * @return true|void
     */
    public static function refund($id,$type=1,$options=[]){
        try{
            OrderModel::startTrans();
            $order = OrderModel::where("id",$id)->find();

            if(empty($order)){
                throw new BaseException("您要查找的订单不存在",0);
            }

            $refund = OrderRefundsModel::where("order_id",$id)->findOrEmpty()->toArray();
            if(empty($refund)){
                $orderGoodsId = OrderGoodsModel::where("order_id",$id)->column("id");
                $refund = [
                    "type"              => 1,
                    "order_id"          => $id,
                    "user_id"           => $order["user_id"],
                    "order_no"          => orderNo(),
                    "audit_status"      => $type == 1 ? 2 : 1,
                    "apply_desc"        => !empty($options["apply_desc"]) ? $options["apply_desc"] : "",
                    "order_amount"      => $order["order_amount"],
                    "order_goods_list"  => implode(",",$orderGoodsId),
                    "create_time"       => time()
                ];
                OrderRefundsModel::create($refund);
            }

            if(isset($refund["id"]) && $refund["audit_status"] == 1){
                throw new BaseException("退款审核中",0);
            }else if($refund["audit_status"] == 3){
                throw new BaseException("商家已拒绝退款",0);
            }

            if($refund["audit_status"] == 1){
                OrderModel::where(["id"=>$order['id']])->save([
                    "refund_status"=>2
                ]);
                OrderModel::commit();
                return true;
            }

            $payment = PaymentModel::where("id",$order["pay_id"])->find();
            if(empty($payment)){
                throw new BaseException("退款方式不存在",0);
            }

            if($payment["code"] == "balance"){
                UsersModel::where(["id"=>$order["user_id"]])->inc("money",$order["order_amount"])->update();
                UsersLogModel::create([
                    "user_id"       => $order["user_id"],
                    "type"          => 3,
                    "operation"     => 0,
                    "value"         => $order["order_amount"],
                    "description"   => '订单退款,订单号：' . $order['order_no'],
                    "create_time"   => time()
                ]);
            } else if($payment["code"] == "alipay"){
                $alipay = (new AlipayPayment())->refund($refund["order_no"],$order["order_amount"]);
                if($alipay->msg != "Success" && $alipay->code != "10000"){
                    throw new BaseException("支付宝退款失败 [CODE:{$alipay->code}]" . $alipay->msg . " [sub_code: {$alipay->subCode}]" . $alipay->subMsg,0);
                }
            }else if($payment["code"] == "wechat"){
                $wechat = (new WechatPayment())->refund([
                    "out_trade_no"  => $order["order_no"],
                    "out_refund_no" => $refund["order_no"],
                    "amount"        => [
                        "refund"    => $order["order_amount"] * 100,
                        "total"     => $order["order_amount"] * 100,
                        "currency"  => "CNY"
                    ],
                    "notify_url"    => url("api/payment.wechat/refund",[],false,true)
                ]);

                if($wechat["status"] != "SUCCESS"){
                    throw new BaseException("微信退款失败，请稍后在试",0);
                }

                OrderModel::where(["id"=>$order['id']])->save([
                    "refund_status"=>3
                ]);
            }

            if(in_array($payment["code"],["balance","alipay"])){
                OrderRefundsModel::where("order_no",$refund["order_no"])->save([
                    "status"        => 2,
                    "audit_status"  => 2,
                    "update_time"   => time()
                ]);

                OrderModel::where(["id"=>$order['id']])->save([
                    "status"=>6,
                    "refund_status"=>4
                ]);
            }

            OrderModel::commit();
            return true;
        }catch (\Exception $ex){
            OrderModel::rollback();
//            throw new $ex;
            throw new BaseException($ex->getMessage());
        }
    }

}