<?php

namespace App\Services\marketing;

use Api\PhpUtils\Http\HttpUtil;
use App\Exception\custom\InterfaceException;
use App\Exception\custom\MarketingException;
use App\Models\marketing\mysql\ColonelDistributorColonel;
use App\Models\marketing\mysql\ColonelDistributorConfig;
use App\Models\marketing\mysql\ColonelDistributorInviteOrder;
use App\Models\marketing\mysql\ColonelDistributorInviteOrderNum;
use App\Models\marketing\mysql\ColonelDistributorPayInfo;
use App\Services\user\UserService;

class PindanActivityInviteOrderService
{
    /**
     * 团长分销下单逻辑
     * @param array $params
     * @return bool
     * @throws MarketingException
     */
    public static function placeOrder($params = [])
    {
        $num = empty($params["num"]) ? 1 : $params["num"];
        $inviteOrderData = [
            "colonel_user_id" => $params["colonel_user_id"],
            "user_id" => $params["user_id"],
            "order_id" => $params["order_id"],
            "refund_time" => null,
        ];

        $inviteOrder = ColonelDistributorInviteOrder::selectMaster("*", $inviteOrderData, []);
        if (!empty($inviteOrder)) {
            return true;
        }

        $timeRange = PindanActivityColonelConfigService::getActivityTimeRange();
        $inviteOrderNumData = [
            "colonel_user_id" => $params["colonel_user_id"],
            "date" => $timeRange['date']
        ];
        $inviteOrderNum = ColonelDistributorInviteOrderNum::selectMaster("*", $inviteOrderNumData, []);

        ColonelDistributorInviteOrder::beginTransaction();
        $addInviteOrderRes = ColonelDistributorInviteOrder::save($inviteOrderData);

        if (!empty($inviteOrderNum)) {
            $addInviteOrderNumRes = ColonelDistributorInviteOrderNum::save(["num[+]" => $num], ["invite_order_num_id" => $inviteOrderNum[0]["invite_order_num_id"]]);
        } else {
            $inviteOrderNumData["num"] = $num;
            $addInviteOrderNumRes = ColonelDistributorInviteOrderNum::save($inviteOrderNumData);
        }

        if (empty($addInviteOrderRes) || empty($addInviteOrderNumRes) || !ColonelDistributorInviteOrder::commit()) {
            ColonelDistributorInviteOrder::rollback();
            throw new MarketingException(["cus" => MarketingException::COMMIT_ERROR]);
        }
        return true;
    }

    /**
     * 团长分销退单逻辑
     * @param array $params
     * @return bool
     * @throws MarketingException
     */
    public static function refundOrder($params = [])
    {
        $orderId = $params["order_id"];

        $inviteOrder = ColonelDistributorInviteOrder::selectMaster("*", ["order_id" => $orderId], []);
        if (!empty($inviteOrder) && $inviteOrder[0]["is_refund"] == ColonelDistributorInviteOrder::IS_REFUND_NO) {
            $inviteOrderData = [
                "colonel_user_id" => $inviteOrder[0]["colonel_user_id"],
                "user_id" => $inviteOrder[0]["user_id"],
                "order_id" => $orderId,
            ];

            $inviteOrderNumData = [
                "colonel_user_id" => $inviteOrder[0]["colonel_user_id"],
                "date" => date("Y-m-d"),
            ];

            ColonelDistributorInviteOrder::beginTransaction();
            $addInviteOrderRes = ColonelDistributorInviteOrder::save([
                "is_refund" => ColonelDistributorInviteOrder::IS_REFUND_YES,
                "refund_time" => date("y-m-d H:i:s")
            ], $inviteOrderData);

            $addInviteOrderNumRes = ColonelDistributorInviteOrderNum::save(["num[-]" => 1], $inviteOrderNumData);

            if (empty($addInviteOrderRes) || empty($addInviteOrderNumRes) || !ColonelDistributorInviteOrder::commit()) {
                ColonelDistributorInviteOrder::rollback();
                throw new MarketingException(["cus" => MarketingException::COMMIT_ERROR]);
            }
        }
        return true;
    }

    /**
     * 团长分销，总收入
     * @param array $params
     * @return array
     */
    public static function incomeStatistics($params = [])
    {
        $userIds = $params["user_ids"];

        $allRewards = ColonelDistributorPayInfo::select(["colonel_user_id", "reward"], ["colonel_user_id" => $userIds], []);
        $allData = [];
        if (!empty($allRewards)) {
            foreach ($allRewards as $item) {
                $allData[$item["colonel_user_id"]][] = $item["reward"];
            }
        }

        $data = [];
        //未结算收益
        $noSettlementStatistics = self::noSettlementStatistics($userIds);
        foreach ($noSettlementStatistics as $userId => $item) {
            $data[$userId]["no_settlement"] = $item;
        }

        foreach ($userIds as $userId) {
            $data[$userId]["all_reward"] = 0;
            if (!empty($allData[$userId])) {
                $data[$userId]["all_reward"] = sprintf("%.1f", array_sum($allData[$userId]) / 100);
            }
        }

        return $data;
    }

    /**
     * 未结算收益
     * @param $userIds
     * @return array
     * @throws InterfaceException
     */
    private static function noSettlementStatistics($userIds)
    {
        $timeRange = self::getNoSettlementTimeRange();
        $inviteOrderNumList = ColonelDistributorInviteOrderNum::select(["colonel_user_id", "num", "date"], [
            "create_time[>]" => $timeRange["start_time"],
            "colonel_user_id" => $userIds,
            ], []);
        $inviteOrderNumData = [];
        $inviteOrderStatistics = [];
        //多个userId, 订单任务累计的未结算收益
        if (!empty($inviteOrderNumList)) {
            foreach ($inviteOrderNumList as $inviteOrderNum) {
                $inviteOrderNumData[$inviteOrderNum["colonel_user_id"]][$inviteOrderNum["date"]] = $inviteOrderNum["num"];
            }

            if (!empty($inviteOrderNumData)) {
                foreach ($inviteOrderNumData as $userId => $itemList) {
                    foreach ($itemList as $date => $num) {
                        $configList = self::getColonelConfig($date);
                        if (!empty($configList)) {
                            foreach ($configList as $config) {
                                if ($num >= $config["assess_order_num"]) {
                                    if (empty($inviteOrderStatistics[$userId])) {
                                        $inviteOrderStatistics[$userId] = 0;
                                    }
                                    $inviteOrderStatistics[$userId] += $config['reward_amount'] * 100;
                                }
                            }
                        }
                    }
                }
            }
        }
        //获取新用户奖励
        $inviteUserData = [];
        $inviteUserStatistics = [];
        $inviteUserList = self::getInviteNewUserList($userIds, $timeRange["start_time"], $timeRange["end_time"]);
        if (!empty($inviteUserList)) {
            foreach ($inviteUserList as $userId => $item) {
                $inviteUserData[$item["inviter_user_id"]][] = $userId;
            }

            foreach ($inviteUserData as $colonelUserId => $item) {
                $inviteUserStatistics[$colonelUserId] = count($item) * 3 * 100;
            }
        }

        $statistic = [];
        foreach ($userIds as $userId) {
            $inviteOrder = empty($inviteOrderStatistics[$userId]) ? 0 : $inviteOrderStatistics[$userId];
            $inviteUser = empty($inviteUserStatistics[$userId]) ? 0 : $inviteUserStatistics[$userId];
            $statistic[$userId] = sprintf("%.1f", ($inviteOrder + $inviteUser) / 100);;

        }
        return $statistic;
    }


    /**
     * 获取未结算收益的时间段
     * @return array|string[]
     */
    public static function getNoSettlementTimeRange() : array
    {
        // 获取活动时间范围
        // 例如当前时间（2021-09-03 11:00:00） 应结算时间为 2021-08-31 12:00:00 ~ 2021-09-03:12:00:00
        // 例如当前时间（2021-09-03 13:00:00） 应结算时间为 2021-09-01 12:00:00 ~ 2021-09-03:12:00:00
        $nowHour = date("H");
        $hour = ' '.PindanActivityColonelConfigService::ACTIVITY_DEFAULT_HOUR . ':00:00';

        if ($nowHour < 12) {
            $startTime = date('Y-m-d', strtotime('-3 day')).$hour;
        } else {
            $startTime   = date('Y-m-d', strtotime('-2 day')).$hour;
        }
        //$endTime = date("Y-m-d").$hour;
        $endTime = date("Y-m-d H:i:s"); // 结束时间应该取当前时间

        return [
            'start_time' => $startTime,
            'end_time' => $endTime,
        ];
    }

    /**
     * 指定日期的团长配置
     * @param $date
     * @return array|mixed
     */
    private static function getColonelConfig($date)
    {
        $config = ColonelDistributorConfig::getRecord([
            'date' => $date,
            'type' => ColonelDistributorConfig::TYPE_COLONEL
        ]);
        if (empty($config)) {
            $config = ColonelDistributorConfig::getRecord([
                'date[<=]' => $date,
                'ORDER'    => ['date' => 'DESC'],
                'LIMIT'    => 1
            ]);
        }
        $configData = [];
        if (!empty($config['data'])) {
            $configData = json_decode($config['data'], true);
        }
        return $configData;
    }

    /**
     * 获取新用户奖励
     * @param $userIds
     * @param $startTime
     * @param $endTime
     * @return array
     * @throws InterfaceException
     */
    private static function getInviteNewUserList($userIds, $startTime, $endTime): array
    {
        $url = config('interface', 'coupon.background.wx_invite_relation_list_by_user_ids');
        if (empty($url)) {
            throw new InterfaceException(['cus' => 0]);
        }

        $res = HttpUtil::get($url,
            ['user_ids' => $userIds, 'start_time' => $startTime, 'end_time' => $endTime]);
        if (!empty($res['response']['result'])) {
            return array_column($res['response']['result'], null, 'user_id');
        }
        return [];
    }

    /**
     * 团长分销，累计转化单数
     * @param array $params
     * @return array
     */
    public static function inviteOrderNumberStatistics($params = [])
    {
        $timeRange = self::getNoSettlementTimeRange();

        $userIds = $params["user_ids"];
        $allNums = ColonelDistributorInviteOrderNum::select(
            ["colonel_user_id", "num"],
            ["colonel_user_id" => $userIds, "create_time[<]" => $timeRange["start_time"]], []);
        $allData = array_column($allNums, null, "colonel_user_id");

        $data = [];
        foreach ($userIds as $userId) {
            $data[$userId]["all_order_num"] = 0;
            if (!empty($allData[$userId])) {
                $data[$userId]["all_order_num"] = $allData[$userId]["num"];
            }
        }
        return $data;
    }

    /**
     *  团长分销，账单详情
     * @param array $params
     * @return array
     */
    public static function getPayInfoList($params = [])
    {
        $userId = $params["user_id"];
        if (empty($userId)) {
            return [];
        }

        $data = $res = [];
        $nowHour = date("H");
        if ($nowHour < 12) {
            $todayNum = 3;
        } else {
            $todayNum = 2;
        }
        for ($i = 0; $i < $todayNum; $i++) {
            $date = date("Y-m-d", strtotime("-$i day"));
            $res[$date]["total"] = 0;
            $res[$date]["date"] = $date;
            $res[$date]["status"] = 2;
            $res[$date]["data"] = [];
        }

        $weekDay = date("Y-m-d", strtotime("-7 day"));
        $payList = ColonelDistributorPayInfo::select("*", [
            "colonel_user_id" => $userId,
            "date[>=]" => $weekDay,
            "ORDER" => ["date" => "DESC"]
        ], []);
        if (!empty($payList)) {
            foreach ($payList as $item) {
                $tempItem = [];
                $tempItem["type"] = $item["type"];
                $tempItem["type_desc"] = ColonelDistributorPayInfo::$typeDesc[$item["type"]];
                $tempItem["invite_user_id"] = $item["invite_user_id"];
                $tempItem["invite_user_nick"] = $item["invite_user_nick"];
                $tempItem["reward"] = $item["reward"];
                $tempItem["finish_num"] = $item["finish_num"];
                $tempItem["status"] = $item["status"];
                $data[$item["date"]][] = $tempItem;
            }

            foreach ($data as $key => $item) {
                $rewards = array_column($item, "reward");
                $total = array_sum($rewards);

                $res[$key]["total"] = $total / 100;
                $res[$key]["date"] = $key;
                $res[$key]["status"] = 1;
                $res[$key]["data"] = $item;
                foreach ($item as $k => $v) {
                    $res[$key]["data"][$k]["reward"] = $v["reward"] / 100;
                }
            }
        }
        return array_values($res);
    }

    /**
     * 团长分销，下单记录
     * @param array $params
     * @return array
     */
    public static function getInviteOrderRecord($params = [])
    {
        $userId = $params["user_id"];
        $lastId = empty($params["last_id"]) ? "" : $params["last_id"];
        $limit = empty($params["page_size"]) ? 10 : $params["page_size"];

        $dateRange = PindanActivityColonelConfigService::getActivityTimeRange();


        $where = [];
        $where["colonel_user_id"] = $userId;
        $where["create_time[>]"] = $dateRange['start_time'];
        $where["create_time[<]"] = $dateRange['end_time'];
        $where["LIMIT"] = $limit;
        $where["ORDER"] = ["invite_order_id" => "DESC"];

        if (!empty($lastId)) {
            $where["invite_order_id[<]"] = $lastId;
        }

        $list = ColonelDistributorInviteOrder::select(["invite_order_id", "user_id", "is_refund"], $where, []);
        if (!empty($list)) {
            $userIds = array_unique(array_column($list, "user_id"));
            $userList = UserService::userWechatBind(["user_id"=>$userIds]);
            if (!empty($userList)) {
                $userList = array_column($userList, null, "user_id");
            }

            $count = count($list);
            foreach ($list as $key => $item) {
                if (!empty($userList[$item["user_id"]])) {
                    $list[$key]["user_nick"] = $userList[$item["user_id"]]["user_nick"];
                    $list[$key]["user_avatar"] = $userList[$item["user_id"]]["user_avatar"];
                } else {
                    $list[$key]["user_nick"] = "";
                    $list[$key]["user_avatar"] = "";
                }
                $lastId = $item["invite_order_id"];
            }
            if ($count < $limit) {
                $lastId = "-1";
            }
        } else {
            $lastId = "-1";
        }
        return ["list" => $list, "last_id" => $lastId];
    }
}