<?php


namespace App\Modules\AdPosition\Services;


use App\Libs\Singleton;
use App\Modules\AdPosition\Models\AdPosition;
use App\Modules\AdPosition\Models\AdPositionDispatch;
use App\Modules\Trade\Services\OrderService;
use App\Modules\User\Models\QappUser;

class AdPositionService
{
    use Singleton;

    /**
     * @param $uid
     * @param $accountId
     * @return array
     */
    public function getAdPositions($uid, $accountId): array
    {
        myLog('getAdPositions')->info('', compact('uid', 'accountId'));
        // 参数判断
        if (empty($uid) || empty($accountId)) {
            return [];
        }

        // 获取所有有效广告位
        $positions = AdPosition::getAllValidAdPositions();
        if (empty($positions)) {
            return [];
        }

        // 获取广告位分配信息
        $positionIds = array_column($positions, 'id');
        $dispatches  = AdPositionDispatch::getValidPositionDispatches($positionIds, $accountId);
        if (empty($dispatches)) {
            return [];
        }

        // 获取用户相关数据
        $userData = $this->getUserFilterData($uid);
        myLog('getAdPositions')->info('', compact('uid', 'userData'));

        // 针对分配数据筛选出优先级最高的分配任务
        $result     = [];
        $dispatches = collect($dispatches)->groupBy('ad_position_id')->all();
        foreach ($positions as $position) {
            // 相关变量获取
            $positionId = getProp($position, 'id');
            $ident      = getProp($position, 'ident');

            // 获取对应广告位所有任务
            $validDispatches = getProp($dispatches, $positionId, []);
            if (empty($validDispatches)) {
                continue;
            }

            // 根据优先级循环匹配，直到匹配到为止
            $validDispatches = collect($validDispatches)->sortByDesc('priority')->all();
            $validDispatch   = [];
            foreach ($validDispatches as $value) {
                // 过滤条件判断
                $filterContentJson = getProp($value, 'filter_condition');
                $matchFilter       = $this->filterDispatch($filterContentJson, $userData);
                if ($matchFilter) {
                    $validDispatch = $value;
                    break;
                }
            }

            // 判断
            if (empty($validDispatch)) {
                continue;
            }

            // 添加到数据中
            $result[$ident][] = $this->buildPositionData($validDispatch, $position);
        }

        return $result;
    }

    /**
     * 用户的数据
     * @param $uid
     * @return array
     */
    private function getUserFilterData($uid): array
    {
        // 获取用户信息
        $user         = QappUser::getUserByUid($uid);
        $registerAt   = getProp($user, 'created_at');
        $registerUnix = strtotime($registerAt);

        // 获取用户付费情况
        $order  = OrderService::getUserLastestOrder($uid);
        $isPaid = $order ? 1 : 0;

        return compact('uid', 'registerUnix', 'isPaid');
    }

    /**
     * 过滤条件筛选
     * @param $filterContentJson
     * @param $userData
     * @return bool
     */
    private function filterDispatch($filterContentJson, $userData): bool
    {
        // 过滤条件
        $filterContent = json_decode($filterContentJson, true);
        if (empty($userData) || empty($filterContentJson) || empty($filterContent)) {
            return true;
        }

        myLog('getAdPositions')->info('', compact('filterContent', 'userData'));

        // 判断注册时间
        $registerFilter = true;
        $registerAtArr  = getProp($filterContent, 'registerAt');
        if ($registerAtArr) {
            // 默认值
            $registerFilter = false;
            $registerUnix   = $userData['registerUnix'];

            // 循环条件，满足一条即可
            foreach ($registerAtArr as $register) {
                $unit  = getProp($register, 'unit');
                $range = getProp($register, 'range');
                sort($range);
                [$min, $max] = $range;
                $startUnix = strtotime('-' . $max . ' ' . $unit);
                $endUnix   = strtotime('-' . $min . ' ' . $unit);
                if ($registerUnix >= $startUnix && $registerUnix <= $endUnix) {
                    $registerFilter = true;
                    break;
                }
            }
        }

        // 判断付费情况
        $paidFilter = true;
        if (getProp($filterContent, 'isPaid') !== '') {
            // 获取用户付费情况
            $isPaid     = getProp($userData, 'isPaid', 0);
            $paidFilter = false;

            // 有付费
            if ($isPaid && (int)getProp($filterContent, 'isPaid') === 1) {
                $paidFilter = true;
            }

            // 未付费
            if (!$isPaid && (int)getProp($filterContent, 'isPaid') === 0) {
                $paidFilter = true;
            }
        }

        // 两者全部满足条件才可展示
        return $registerFilter && $paidFilter;
    }

    /**
     * 返回可显示数据
     * @param $validDispatch
     * @param $position
     * @return array
     */
    private function buildPositionData($validDispatch, $position): array
    {
        if (empty($validDispatch)) {
            return [];
        }

        // 链接做特殊处理
        $url    = getProp($validDispatch, 'link_url');
        $urlArr = parse_url($url);
        parse_str(getProp($urlArr, 'query'), $queryArr);

        // 广告位图片
        $image = getProp($validDispatch, 'image_url');
        if (empty($image)) {
            $image = getProp($position, 'default_img');
        }

        return [
            'img'    => $image,
            'url'    => getProp($urlArr, 'path'),
            'title'  => getProp($validDispatch, 'title'),
            'params' => $queryArr ?: (object)[]
        ];
    }
}