<?php
/**
 *
 * @file:OrderService.php
 * @Date: 2023/5/23
 * @Time: 13:40
 */


namespace Modules\Channel\Services\Order;

use Illuminate\Support\Facades\DB;
use Modules\Channel\Models\Order;
use Modules\Channel\Models\UserHasMiniprograms;
use Modules\Manage\Models\Miniprogram;
use Modules\User\Models\User;

class OrderService
{

    /**
     *  订单列表查询
     * name: getOrderList
     * @param array $param
     * date 2023/05/23 13:45
     */
    public static function getOrderList(array $param, $isAll = false)
    {
        $list = self::getOrderQuerySql($param)->select("orders.*",'orders_refund_verify.id as refund_id', 'pay_merchants.name as pay_merchant_name', 'pay_merchants.payee_name', 'pay_merchants.pay_appid', 'miniprogram.play_name', "miniprogram.name as xcx_name", 'promotions.name as promotion_title')->orderBy("orders.id", 'desc');

        if ($isAll) {
            $list = $list->get();
        } else {
            $list = $list->paginate(getProp($param, 'limit', 15));
        }

        if (!$list->isEmpty()) {
            $status = array_column(self::getOrderPayType(), null, 'value');
            $types = array_column(self::getOrderType(), null, 'value');
            foreach ($list as $val) {
                $val->username = $val->user_id > 0 ? User::where('id', $val->user_id)->value('username') : "";
                $val->company_name = $val->puser_id > 0 ? DB::table('users')->where('id', $val->puser_id)->value("username") : "-";
                $val->total_count = Order::where('uid', $val->uid)->where('id', "<=", $val->id)->count();
                if ($val->user_id > 0) {
                    $val->caompany_count = Order::where('uid', $val->uid)->where('status','<>', 'UNPAID')->where('puser_id', '>', 0)->where('puser_id', $val->puser_id)->where('id', "<=", $val->id)->count();
                    $val->promotion_count = Order::where('uid', $val->uid)->where('status','<>', 'UNPAID')->where('puser_id', '>', 0)->where('puser_id', $val->puser_id)->where('user_id', ">", 0)->where('user_id', $val->user_id)->where('id', "<=", $val->id)->count();
                } else {
                    $val->caompany_count = Order::where('uid', $val->uid)->where('status','<>', 'UNPAID')->where('puser_id', '>', 0)->count();
                    $val->promotion_count = Order::where('uid', $val->uid)->where('status','<>', 'UNPAID')->where('user_id', '>', 0)->count();
                }
                $val->pay_appid = $val->pay_appid ?: '-';
                $val->pay_merchant_name = $val->pay_merchant_name ?: '-';
                $val->payee_name = $val->payee_name ?: '-';
                $val->xcx_name = $val->xcx_name ?: '-';
                $val->play_name = $val->play_name ?: '-';
                $val->promotion_title = $val->promotion_title ?: '-';
                $val->tip_text = $types[$val->order_type]['name'] ?? "-";
                $val->status_txt = $status[$val->status]['name'] ?? "-";
                $val->can_apply = $val->refund_id < 1 && $val->status == 'PAID';
                $val->pay_name = '微信支付';
                unset($val->refund_id);
            }
        }

        return $list;
    }


    /**
     *  充值类型
     * name: getOrderType
     * @return \string[][]
     * date 2023/06/02 09:56
     */
    public static function getOrderType()
    {
        return [
            ["value" => "COIN", "name" => "普通充值"],
            ["value" => 'MONTH', "name" => '包月'],
            ["value" => 'QUARTER', "name" => '包季'],
            ["value" => 'YEAR', "name" => '包年'],
            ["value" => "FIRST_COIN", "name" => "首充"]
        ];
    }

    /**
     *  订单状态
     * name: getOrderPayType
     * @return \string[][]
     * date 2023/06/02 09:57
     */
    public static function getOrderPayType()
    {
        return [
            ["value" => "PAID", "name" => "已支付"],
            ["value" => 'REFUND', "name" => '已退款'],
            ["value" => 'UNPAID', "name" => '未支付'],
        ];
    }

    private static function getOrderQuerySql(array $param)
    {
        $sql = DB::table('orders')->leftJoin('orders_refund_verify','orders.id','=','orders_refund_verify.order_id')->leftJoin('miniprogram', 'miniprogram.id', '=', 'orders.miniprogram_id')->leftJoin('promotions', 'promotions.id', '=', 'orders.promotion_id')->leftJoin('pay_merchants', 'pay_merchants.id', '=', 'orders.pay_merchant_id');
        // 优化师查询
        if (!empty(getProp($param, 'user_id'))) {
            $sql->where('orders.user_id', $param['user_id']);
        }
        // 公司查询
        if (!empty(getProp($param, 'puser_id'))) {
            $sql->where('orders.puser_id', $param['puser_id']);
        }
        // 小程序
        if (!empty(getProp($param, 'miniprogram_id'))) {
            $sql->where('orders.miniprogram_id', $param['miniprogram_id']);
        }

        // 推广id
        if (!empty(getProp($param, 'promotion_id'))) {
            $sql->where('orders.promotion_id', $param['promotion_id']);
        }
        // 订单状态查询
        if (!empty(getProp($param, 'status'))) {
            $sql->where('orders.status', $param['status']);
        }

        // 充值项类型
        if (!empty(getProp($param, 'order_type'))) {
            $sql->where('orders.order_type', $param['order_type']);
        }
        // 用户
        if (!empty(getProp($param, 'uid'))) {
            $sql->where('orders.uid', $param['uid']);
        }
        // 订单号查询
        if (!empty(getProp($param, 'trade_no'))) {
            $sql->where('orders.trade_no', "like", "%" . $param['trade_no'] . "%");
            // $sql->where('orders.trade_no',  $param['trade_no']);
        }
        if (!empty(getProp($param, 'trade_no'))) {
            // $sql->where('orders.trade_no', "like", "%" . $param['trade_no'] . "%");
            $sql->where('orders.trade_no', $param['trade_no']);
        }
        // 支付时间
        if (!empty(getProp($param, 'pay_end_at_start'))) {
            $sql->where('orders.pay_end_at', ">=", $param['pay_end_at_start']);
        }
        if (!empty(getProp($param, 'pay_end_at_end'))) {
            $end = $param['pay_end_at_end'];
            if ($end == getProp($param, 'pay_end_at_start', '')) {
                $end = date("Y-m-d", strtotime($end)) . " 23:59:59";
            }
            $sql->where('orders.pay_end_at', "<=", $end);
        }
        // 创建时间
        if (!empty(getProp($param, 'created_at_start'))) {
            $sql->where('orders.created_at', '>=', $param['created_at_start']);
        }

        if (!empty(getProp($param, 'created_at_end'))) {
            $end = $param['created_at_end'];
            if ($end == getProp($param, 'created_at_start', '')) {
                $end = date("Y-m-d", strtotime($end)) . " 23:59:59";
            }
            $sql->where('orders.created_at', "<=", $end);
        }

        // 支付配置信息查询
        if (getProp($param, 'pay_merchant_name', '')) {
            // 支付名称
            $sql->where("pay_merchants.name", $param['pay_merchant_name']);
        }
        if (getProp($param, 'payee_name', '')) {
            // 收款主体
            $sql->where("pay_merchants.payee_name", "like", "%" . $param['payee_name'] . "%");
        }
        if (getProp($param, 'pay_appid', '')) {
            // 商户号
            $sql->where("pay_merchants.pay_appid", $param['pay_appid']);
        }
        return $sql;
    }

    /**
     *  用户订单小程选择列表
     * name: userUseProgramsList
     * @param mixed $uid
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection
     * date 2023/05/23 17:51
     */
    public static function userUseProgramsList(mixed $uid, $name = "", $limit = 20)
    {

        $operateUser = User::find($uid);
        $operateUserRoles = $operateUser->roles->pluck('identify');
        if ($operateUserRoles->contains('company') || $operateUserRoles->contains('optimizer')) {
            $list = UserHasMiniprograms::query()->join('miniprogram', 'miniprogram.id', '=', 'user_has_miniprograms.miniprogram_id')
                ->where('uid', $uid)
                ->groupBy("user_has_miniprograms.miniprogram_id")
                ->select('user_has_miniprograms.miniprogram_id', 'miniprogram.name', 'miniprogram.play_name');
            if ($name) {
                $list->where('name', "like", "%" . $name . "%");
            }
            return $list->orderBy('miniprogram.id', 'desc')->limit($limit)->get();
        } else {
            if ($name) {
                return DB::table('miniprogram')->where('name', "like", "%" . $name . "%")->select("id as miniprogram_id", "name", "play_name")->limit($limit)->get();
            }
            return DB::table('miniprogram')->select("id as miniprogram_id", "name", "play_name")->orderBy('id', 'desc')->limit($limit)->get();

        }

    }

    /**
     *  推广列表选择项
     * name: promotionsOptions
     * @param mixed $uid
     * @param mixed $title
     * @return \Illuminate\Support\Collection
     * date 2023/05/23 18:13
     */
    public static function promotionsOptions(mixed $uid, mixed $title, mixed $miniprogram_id, mixed $limit = 10)
    {
        $operateUser = User::find($uid);
        $operateUserRoles = $operateUser->roles->pluck('identify');
        $list = DB::table('promotions')->select('id as promotion_id', 'name');
        if ($operateUserRoles->contains('optimizer')) {
            if ($miniprogram_id) {
                $list->where('miniprogram_id', $miniprogram_id);
            }
            if ($title) {
                $list->where('name', 'like', "%" . $title . "%");
            }

            return $list->where('uid', $uid)->orderBy('id', 'desc')->limit($limit)->get();
        } else if ($operateUserRoles->contains('company')) {
            $list = DB::table('promotions')->join('users', 'users.id', "promotions.uid")
                ->where('users.pid', $uid)->orWhere("promotions.uid", $uid)->select('promotions.id as promotion_id', 'promotions.name');
            if ($title) {
                $list->where('promotions.name', 'like', "%" . $title . "%");
            }
            if ($miniprogram_id) {
                $list->where('promotions.miniprogram_id', $miniprogram_id);
            }
            return $list->orderBy('promotions.id', 'desc')->limit($limit)->get();

        } else {
            if ($miniprogram_id) {
                $list->where('miniprogram_id', $miniprogram_id);
            }
            if ($title) {
                $list->where('name', 'like', "%" . $title . "%");
            }
            return $list->orderBy('id', 'desc')->limit($limit)->get();
        }
    }

    /***
     * 订单列表优化师选择项
     * name: promotionsUsers
     * @param mixed $pid
     * @param mixed $name
     * @param mixed $limit
     * date 2023/05/26 09:22
     */
    public static function promotionsUsers(mixed $pid, mixed $name, mixed $miniprogram_id, mixed $limit = 10)
    {
        if ($pid > 0) {
            $list = DB::table('users')->where('pid', $pid)->select('users.id as user_id', 'users.username as  name');
            if ($name) {
                $list->where('username', 'like', "%" . $name . "%");
            }
            if ($miniprogram_id > 0) {
                $list->join('user_has_miniprograms', 'user_has_miniprograms.uid', 'users.id')
                    ->where('user_has_miniprograms.miniprogram_id', $miniprogram_id);
            }

            return $list->orderBy('users.id', 'desc')->limit($limit)->get();
        }

        $list = DB::table('users')->join('user_has_roles', 'users.id', "user_has_roles.user_id")->join('roles', 'roles.id', 'user_has_roles.role_id')
            ->select('users.id as user_id', 'users.username as  name')->where('roles.identify', 'optimizer');
        if ($miniprogram_id > 0) {
            $list->join('user_has_miniprograms', 'user_has_miniprograms.uid', 'users.id')
                ->where('user_has_miniprograms.miniprogram_id', $miniprogram_id);
        }
        if ($name) {
            $list->where('users.username', 'like', "%" . $name . "%");
        }
        return $list->orderBy('users.id', 'desc')->limit($limit)->get();
    }
}