<?php


namespace App\Http\Logic\Cron;


use App\Exceptions\CommonException;
use App\Http\Bean\Cron\logic\HandleOrderParamBean;
use App\Http\Bean\Util\Jutuike\GetOrderListParamBean;
use App\Http\Bean\Util\Meituan\OrderListParamBean;
use App\Http\Bean\Util\Pdd\Ddk\OrderListIncrementGetParamBean;
use App\Http\Enum\ErrorEnum;
use App\Http\Enum\OrderStatusEnum;
use App\Http\Enum\PlatformTypeEnum;
use App\Http\Logic\BaseLogic;
use App\Http\Logic\Order\OrderLogic;
use App\Http\Utils\BaseUtil;
use App\Http\Utils\Jutuike\JutuikeUtil;
use App\Http\Utils\LoggerFactoryUtil;
use App\Http\Utils\Meituan\MeituanLianmengUtil;
use App\Http\Utils\Pdd\DuoDuoKeUtil;
use App\Http\Utils\WechatAccountUtil;
use App\Models\CategoryModel;
use App\Models\UserCashModel;
use App\Models\UserFinanceModel;
use App\Models\UserModel;
use App\Models\UserOrderCommissionModel;
use App\Models\UserOrderModel;
use App\Models\WechatAccountModel;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\DB;

class CronLogic extends BaseLogic
{
    /**
     * 获取美团订单
     */
    public static function meituanOrderslogic()
    {
        $params = request()->all();
        $arr = [
            "appkey"=>env("MEITUAN_LIANMENG_KEY"),
            "type"=>$params["order_type"],
            "startTime"=>time()-$params["minute"]*60,
            "endTime"=>time(),
//            "startTime"=>strtotime("2021-09-22 11:25:00"),
//            "endTime"=>time(),
            "page"=>1,
            "limit"=>30,
            "queryTimeType"=>2,
        ];

        $instance = new LoggerFactoryUtil(CronLogic::class);
        $instance->info("获取订单数据开始");
        $bean = new OrderListParamBean($arr);
        $res = MeituanLianmengUtil::orderList($bean);
//        dd($res);
        $instance->info("美团返回数据:".json_encode($res));
        $instance->info("订单数量:".$res["total"]);
        if($res){
            //存在数据,写入订单数据表
            if($res["total"]){
                $instance->info("订单数据:".json_encode($res));
                BaseUtil::sendBaoJing("","获取到订单数量:".$res["total"],"定时获取美团订单");
                //处理订单
                self::checkOrder($res["dataList"],$params["order_type"]);
                //判断订单数量是否大于分页
                $pageNum = ceil($res["total"]/100)-1;
                if($pageNum){
                    for ($i=1;$i<=$pageNum;$i++){
                        $arr["page"]++;
                        $bean = new OrderListParamBean($arr);
                        $res = MeituanLianmengUtil::orderList($bean);
                        if ($res) {
                            //存在数据,写入订单数据表
                            if ($res["total"]) {
                                self::checkOrder($res["dataList"],$params["order_type"]);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理订单
     */
    protected static function checkOrder($orders,$orderType)
    {
        foreach ($orders as $data) {
            switch ($data["status"]) {
                case 1://已付款
                    $orderStatus = OrderStatusEnum::ALREADY_PAY;
                    break;
                case 8://已收货
                    $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
                    break;
                case 9://已退款或风控
                    $orderStatus = OrderStatusEnum::ALREADY_REFUND;
                    break;
            }

            $params = [
                "spreadSonType" => 0,//订单子类型
                "orderNumber" => $data["orderid"],//订单编号
                "payTime" => date("Y-m-d H:i:s", $data["paytime"]),//支付时间
                "orderPrice" => $data["payprice"] * 100,//订单金额
                "orderCommission" => $data["profit"] * 100,//订单佣金
                "orderTitle" => $data["smstitle"],//订单标题
                "orderRefundPrice" => isset($data["refundprice"]) ? $data["refundprice"] * 100 : 0,//退款金额
                "orderRefundTime" => isset($data["refundtime"]) ? date("Y-m-d H:i:s", $data["refundtime"]) : null,//退款时间
                "orderRefundCommission" => isset($data["refundprofit"]) ? $data["refundprofit"] : 0,//退款佣金
                "orderStatus" => $orderStatus,//订单状态
                "orderCouponPrice" => 0,//订单优惠
                "productImgUrl" => "https://pic.rmb.bdstatic.com/bjh/f049242a789a22fb1a412bb6418c52e2.jpeg",//商品图片
                "spreadType"=>PlatformTypeEnum::PLATFORM_MEITUAN,//订单类型
                "userSpreadId"=>$data["sid"],//用户推广位
                "platformSpreadId"=>$data["sid"],//平台推广位
                "createdAt"=>date("Y-m-d H:i:s", $data["paytime"])
            ];

            $bean = new HandleOrderParamBean($params);
            OrderLogic::handleOrderLogic($bean);
        }
    }

    /**
     * 聚推客订单逻辑
     */
    public static function jutuikeOrdersLogic()
    {
        $params = request()->all();
        $startTime = date("Y-m-d H:i:s",time()-600);
        $endTime = date("Y-m-d H:i:s");
        if(isset($params["start_time"])){
            $startTime = $params["start_time"];
        }
        if (isset($params["end_time"])){
            $endTime= $params["end_time"];
        }
        $page = 1;
        $params = [
            "start_time"=>$startTime,
            "end_time"=>$endTime,
            "query_type"=>2,
            "page"=>$page,
            "pageSize"=>100
        ];
        $bean = new GetOrderListParamBean($params);
        $data = JutuikeUtil::getOrderList($bean);
        $instance = new LoggerFactoryUtil(CronLogic::class);
        $instance->info("上游返回数据:".json_encode($data));
        if($data["code"]!=1){
            //上游错误
            return;
        }
        //判断是否存在订单
        $orderLists = $data["data"]["data"];

        if(count($orderLists)){
            BaseUtil::sendBaoJing("","获取到订单数量:".count($orderLists),"定时获取聚推客订单");
        }

        foreach ($orderLists as $orderList){
            self::handleOrderLogic($orderList);
        }
    }

    public static function handleOrderLogic($orderList)
    {
        //判断订单状态
        switch ($orderList["status"]){
            case 0://未付款
                $orderStatus = OrderStatusEnum::PRE_PAY;
                break;
            case 1://已付款
                $orderStatus = OrderStatusEnum::ALREADY_PAY;
                break;
            case 2://待结算
                $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
                break;
            case 3://已结算
                $orderStatus = OrderStatusEnum::ALREADY_FINISH;
                break;
            case 4://无效订单
                $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
                break;
        }
        //获取活动图片
        $actImgUrl = CategoryModel::query()
            ->where("platform_type",PlatformTypeEnum::PLATFORM_JUTUIKE)
            ->where("activity_id",$orderList["act_id"])
            ->value("category_img_url");
        $params = [
            "spreadSonType" => 0,//订单子类型
            "orderNumber" => $orderList["order_sn"],//订单编号
            "payTime" => $orderList["pay_time"],//支付时间
            "orderPrice" => $orderList["order_price"] * 100,//订单金额
            "orderCommission" => $orderList["jtk_share_fee"] * 100,//订单佣金
            "orderTitle" => $orderList["order_title"],//订单标题
            "orderRefundPrice" => 0,//退款金额
            "orderRefundTime" => null,//退款时间
            "orderRefundCommission" => 0,//退款佣金
            "orderStatus" => $orderStatus,//订单状态
            "orderCouponPrice" => 0,//订单优惠
            "productImgUrl" => $actImgUrl,//商品图片
            "spreadType"=>PlatformTypeEnum::PLATFORM_JUTUIKE,//订单类型
            "userSpreadId"=>$orderList["sid"],//用户推广位
            "platformSpreadId"=>$orderList["sid"],//平台推广位
            "createdAt"=>$orderList["create_time"],//订单创建时间
        ];

        $bean = new HandleOrderParamBean($params);
        OrderLogic::handleOrderLogic($bean);
    }

    /**
     * 获取拼多多订单逻辑
     */
    public static function pddOrdersLogic()
    {
        $params = [
            "startUpdateTime"=>time()-600,
            "endUpdateTime"=>time()
        ];
        $bean = new OrderListIncrementGetParamBean($params);
        $res = DuoDuoKeUtil::orderListIncrementGet($bean);
        $instance = new LoggerFactoryUtil(CronLogic::class);
        $instance->info("上游返回信息:".json_encode($res));
        if (isset($res["error_response"])){
            return;
        }
        if($res["order_list_get_response"]["total_count"]){
            BaseUtil::sendBaoJing("","获取到订单数量:".$res["order_list_get_response"]["total_count"],"定时获取拼多多订单");
        }
        //获取数据
        $datas = $res["order_list_get_response"]["order_list"];
        foreach ($datas as $orderList){
            switch ($orderList["order_status"]){
                case 0:
                    //已支付
                    $orderStatus = OrderStatusEnum::ALREADY_PAY;
                    break;
                case 1:
                    //已成团
                    $orderStatus = OrderStatusEnum::ALREADY_PAY;
                    break;
                case 2:
                    //确认收货
                    $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
                    break;
                case 3:
                    //审核成功
                    $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
                    break;
                case 4:
                    //审核失败(不可提现)
                    $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
                    break;
                case 5:
                    //已经结算
                    $orderStatus = OrderStatusEnum::ALREADY_RECEIVE;
                    break;
                case 10:
                    //已处罚
                    $orderStatus = OrderStatusEnum::ALREADY_CANCEL;
                    break;
            }
            $params = [
                "spreadSonType" => 0,//订单子类型
                "orderNumber" => $orderList["order_sn"],//订单编号
                "payTime" => date("Y-m-d H:i:s",$orderList["order_pay_time"]),//支付时间
                "orderPrice" => $orderList["order_amount"],//订单金额
                "orderCommission" => $orderList["promotion_amount"],//订单佣金
                "orderTitle" => $orderList["goods_name"],//订单标题
                "orderRefundPrice" => 0,//退款金额
                "orderRefundTime" => null,//退款时间
                "orderRefundCommission" => 0,//退款佣金
                "orderStatus" => $orderStatus,//订单状态
                "orderCouponPrice" => 0,//订单优惠
                "productImgUrl" => "https://pic.rmb.bdstatic.com/bjh/6d9fb4a81eb5fc933da8949854c4fab2.jpeg",//商品图片
                "spreadType"=>PlatformTypeEnum::PLATFORM_PINGDUODUO,//订单类型
                "userSpreadId"=>$orderList["p_id"],//用户推广位
                "platformSpreadId"=>$orderList["p_id"],//平台推广位
                "createdAt"=>date("Y-m-d H:i:s",$orderList["order_create_time"]),//订单创建时间
            ];

            $bean = new HandleOrderParamBean($params);
            OrderLogic::handleOrderLogic($bean);
        }
    }

    /**
     * 发送用户下单模版
     */
    public static function sendOrderTemplateLogic()
    {
        $instance = new LoggerFactoryUtil(CronLogic::class);
        //1.新增粉丝通知
        $userFans = UserModel::query()
            ->where("invite_user_id","<>",0)
            ->where("user_notify_status",0)
            ->get();
        foreach ($userFans as $userFan){
            //获取推荐人
            $inviteUser = UserModel::findById($userFan->invite_user_id);
            if($inviteUser){
                try{
                    //获取公众号实例
                    $app = WechatAccountUtil::getAppByID($userFan->wechat_account_id);
                    $data = [
                        'touser' => $inviteUser->user_open_id,
                        'template_id' => env("WECHAT_FANS_TEMPLATE_URL"),
                        'url' => env("WECHAT_FANS_URL"),
                        'data' => [
                            'first' => "亲,您有新的粉丝",
                            'keyword1' => $userFan->user_nickname,
                            'keyword2' => $userFan->id+100000,
                            "remark"=>"粉丝将提供分享佣金,粉丝越多比例越高哦,点击查看详情"
                        ],
                    ];
                    $res = $app->template_message->send($data);
                    $instance->info("粉丝通知微信返回结果:".json_encode($res));
                }catch (\Throwable $exception){
                    $instance->info("粉丝通知结果异常:".$exception->getMessage());
                }
                UserModel::query()->where("id",$userFan->id)->update(
                    [
                        "user_notify_status"=>1
                    ]
                );
            }
        }
        //2.获取自购已支付且未通知进行模版推送
        $orders = UserOrderCommissionModel::query()
            ->where("commission_status",0)
            ->where("order_commission",">",0)
            ->where("user_id","<>",0)
            ->where("order_notify_status",0)
            ->limit(10)
            ->get();
        foreach ($orders as $order){
            //判断是否自购订单
            if($order->user_provider_id){
                //反佣订单
                $user = UserModel::findById($order->user_id);
                if($user){
                    try{
                        //获取公众号实例
                        $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
                        $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
                        $privideUser = UserModel::findById($order->user_provider_id);
                        $data = [
                            'touser' => $user->user_open_id,
                            'template_id' => env("WECHAT_FANS_ORDER_TEMPLATE_URL"),
                            'url' => env("WECHAT_FANS_ORDER_URL"),
                            'data' => [
                                'first' => "粉丝下单成功通知",
                                'keyword1' => $order->order_number,
                                'keyword2' => $tmpOrder->product_name,
                                'keyword3' => $order->created_at,
                                'keyword4' => round($tmpOrder->order_price/100,2)."元",
                                'keyword5' => $privideUser->user_nickname,
                                "remark"=>"您的粉丝有新的订单,分享佣金已产生,3天后结算到您账户中,点击详情跳转粉丝订单"
                            ],
                        ];
                        $res = $app->template_message->send($data);
                        $instance->info("粉丝下单微信返回结果:".json_encode($res));
                    }catch (\Throwable $exception){
                        $instance->info("粉丝下单通知结果异常:".$exception->getMessage());
                    }
                }
            }else{
                $user = UserModel::findById($order->user_id);
                if($user){
                    try{
                        //获取公众号实例
                        $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
                        $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
                        $data = [
                            'touser' => $user->user_open_id,
                            'template_id' => env("WECHAT_ORDER_TEMPLATE_URL"),
                            'url' => env("WECHAT_ORDER_URL"),
                            'data' => [
                                'first' => "下单成功通知",
                                'keyword1' => $order->created_at,
                                'keyword2' => $tmpOrder->product_name,
                                'keyword3' => $order->order_number,
                                "remark"=>"感谢您的使用,每月20号结算上个月的佣金,将会结算到您的账户中点击详情跳转我的订单"
                            ],
                        ];
                        $res = $app->template_message->send($data);
                        $instance->info("自购下单微信返回结果:".json_encode($res));
                    }catch (\Throwable $exception){
                        $instance->info("自购下单通知结果异常:".$exception->getMessage());
                    }
                }
            }
            UserOrderCommissionModel::query()->where("id",$order->id)->update(
                [
                    "order_notify_status"=>1
                ]
            );
        }

        //3.获取已结算订单,并通知
        $completeOrders = UserOrderCommissionModel::query()
            ->where("commission_status",1)
            ->where("order_commission",">",0)
            ->where("user_id","<>",0)
            ->where("order_complete_notify_status",0)
            ->limit(10)
            ->get();
        foreach ($completeOrders as $order){
            $user = UserModel::findById($order->user_id);
            if($user){
                try{
                    //获取公众号实例
                    $app = WechatAccountUtil::getAppByID($user->wechat_account_id);
                    $tmpOrder = UserOrderModel::query()->where("order_number",$order->order_number)->first();
                    $data = [
                        'touser' => $user->user_open_id,
                        'template_id' => env("WECHAT_COMPLETE_ORDER_TEMPLATE_URL"),
                        'url' => env("WECHAT_BALANCE_URL"),
                        'data' => [
                            'first' => "订单:[".$tmpOrder["order_number"]."]佣金已结算完成",
                            'keyword1' => round($order->order_commission/100,2)."元",
                            'keyword2' => round($tmpOrder->order_price/100,2)."元",
                            'keyword3' => $order->updated_at,
                            "remark"=>"订单佣金已结算完成,感谢您的使用,点击详情跳转我的账户"
                        ],
                    ];
                    $res = $app->template_message->send($data);
                    $instance->info("订单结算微信返回结果:".json_encode($res));
                }catch (\Throwable $exception){
                    $instance->info("订单结算通知结果异常:".$exception->getMessage());
                }
            }
            UserOrderCommissionModel::query()->where("id",$order->id)->update(
                [
                    "order_complete_notify_status"=>1
                ]
            );
        }
    }

    /**
     * 结算佣金逻辑(每月的20号18点结算上个月的佣金)
     */
    public static function settlementOrderCommissionLogic()
    {
        //获取上个月的开始结束时间
        $startTime = date("Y-m-d",strtotime("-1 month"))." 00:00:00";
        $endTime = date("Y-m-")."01 00:00:00";
        //获取上个月未结算的订单且未退款
        UserOrderCommissionModel::query()
            ->where("commission_status",0)
            ->where("order_commission",">",0)
            ->where("user_id","<>",0)
            ->where("order_complete_notify_status",0)
            ->where("created_at","<",$endTime)
            ->chunk(100,function ($orderCommissions){
                foreach ($orderCommissions as $orderCommission){
                    try{
                        //开启事务
                        DB::beginTransaction();
                        //1.修改用户的余额
                        $user = UserModel::query()->lock(true)->find($orderCommission["user_id"]);
                        if($user){
                            $userRes = UserModel::query()
                                ->where("id",$orderCommission["user_id"])
                                ->increment("user_balance",$orderCommission["order_commission"]);
                            if(!$userRes){
                                DB::rollBack();
                                throw new CommonException(ErrorEnum::ERROR_SYSTEM);
                            }
                            //2.添加用户流水记录
                            $logRes = UserFinanceModel::query()
                                ->insert(
                                    [
                                        "user_id"=>$orderCommission["id"],
                                        "order_number"=>$orderCommission["order_number"],
                                        "user_before_balance"=>$user["user_balance"],
                                        "user_after_balance"=>$orderCommission["order_commission"]+$user["user_balance"],
                                        "finance_balance"=>$orderCommission["order_commission"],
                                        "finance_remark"=>"订单佣金结算",
                                        "finance_type"=>1,
                                        "finance_number"=>uniqid("fbt-"),
                                        "created_at"=>date("Y-m-d H:i:s"),
                                        "updated_at"=>date("Y-m-d H:i:s")
                                    ]
                                );
                            if(!$logRes){
                                DB::rollBack();
                                throw new CommonException(ErrorEnum::ERROR_SYSTEM);
                            }
                            //3.修改佣金记录为已结算
                            $commissionRes = UserOrderCommissionModel::query()
                                ->where("id",$orderCommission["id"])
                                ->update(
                                    [
                                        "commission_status"=>1,
                                        "updated_at"=>date("Y-m-d H:i:s")
                                    ]
                                );
                            if(!$commissionRes){
                                DB::rollBack();
                                throw new CommonException(ErrorEnum::ERROR_SYSTEM);
                            }
                            DB::commit();
                        }
                    }catch (\Throwable $exception){}
                }
            });
    }

    /**
     * 处理提现打款逻辑
     */
    public static function transferFinanceLogic()
    {
        $account = WechatAccountModel::query()
            ->where("wechat_app_code","fanbuting")
            ->first();
        $config = [
            "app_id"=>$account["wechat_app_id"],
            "mch_id"=>$account["account_mch_id"],
            "key"=>$account["account_key"],
            "cert_path"=>$account["account_cert_path"],
            "key_path"=>$account["account_key_path"]
        ];
        $app = Factory::payment($config);
        //获取已审核且未打款的提现记录
        $cashLogs = UserCashModel::query()
            ->where("check_status",2)
            ->where("cash_status",0)
            ->get();
        if(!$cashLogs){
            return ;
        }

        //将打款记录修改为执行中
        $logIds = [];
        foreach ($cashLogs as $cashLog){
            $logIds[] = $cashLog["id"];
        }
        UserCashModel::query()
            ->whereIn("id",$logIds)
            ->update(
                [
                    "cash_status"=>1
                ]
            );

        foreach ($cashLogs as $cashLog){
           //1.获取用户的openId
           $user = UserModel::query()->find($cashLog["user_id"]);
           if($user){
               $res = $app->transfer->toBalance(
                   [
                       "partner_trade_no"=>$cashLog["cash_order_number"],
                       "openid"=>$user["user_open_id"],
                       "check_name"=>"NO_CHECK",//不校验姓名
                       "re_user_name"=>"",//真实姓名
                       "amount"=>$cashLog["cash_money"],
                       "desc"=>"用户提现"
                   ]
               );
               //判断是否支付成功
               if($res["return_code"]=="SUCCESS" && $res["result_code"]=="SUCCESS"){
                   UserCashModel::query()
                       ->where("id",$cashLog["id"])
                       ->update(
                           [
                               "cash_status"=>2,
                               "upstream_response"=>json_encode($res),
                               "cash_receive_at"=>date("Y-m-d H:i:s")
                           ]
                       );

               }else{
                   //打款失败
                   UserCashModel::query()
                       ->where("id",$cashLog["id"])
                       ->update(
                           [
                                "cash_status"=>3,
                               "upstream_response"=>json_encode($res)
                           ]
                       );
               }
           }
        }
    }

    /**
     * 打款失败退款逻辑
     */
    public static function callbackCashLogic()
    {
        //获取已审核且未打款的提现记录
        $cashLogs = UserCashModel::query()
            ->where("callback_status",0)
            ->where(function ($query){
                $query->where("check_status",3)
                    ->orWhere("cash_status",3);
            })
            ->get();

        if(!$cashLogs){
            return;
        }

        foreach ($cashLogs as $cashLog){
            DB::beginTransaction();
            //获取用户
            $user = UserModel::query()->lock(true)->find($cashLog["user_id"]);
            //1.用户金额增加
            $userRes = UserModel::query()
                ->where("id",$user["user_id"])
                ->increment("user_balance",$cashLog["cash_money"]);
            if(!$userRes){
                DB::rollBack();
                break;
            }
            //2.添加流水记录
            $financeRes = UserFinanceModel::query()->insert(
                [
                    "user_id"=>$cashLog["user_id"],
                    "user_before_balance"=>$user["user_balance"],
                    "user_after_balance"=>$user["user_balance"]+$cashLog["cash_money"],
                    "finance_balance"=>$cashLog["cash_money"],
                    "finance_remark"=>"提现失败退回,原提现记录ID为:".$cashLog["id"],
                    "finance_type"=>1,
                    "finance_number"=>BaseUtil::getOrderNumber(),
                    "created_at"=>date("Y-m-d H:i:s"),
                    "updated_at"=>date("Y-m-d H:i:s"),
                ]
            );
            if(!$financeRes){
                DB::rollBack();
                break;
            }
            //3.修改提现记录为退款成功
            $cashRes =  UserCashModel::query()
                ->where("id",$cashLog["id"])
                ->update([
                    "callback_status"=>1
                ]);
            if(!$cashRes){
                DB::rollBack();
                break;
            }
            DB::commit();
        }

    }

}