<?php


namespace App\Services\marketing;

use Api\PhpUtils\Http\Request;
use App\Models\marketing\mysql\BusinessCircle;
use App\Models\marketing\mysql\MarketingTakePlace;
use App\Models\marketing\mysql\Tag;
use App\Models\marketing\mysql\TakePlace;
use App\Exception\custom\MarketingException;
use Api\PhpUtils\Common\Geo;

class TakePlaceService
{
    /**
     * 获取自提点列表（op 后台）
     *
     * 支持关键词（自提点名称/联系人）搜索
     * @param array $params
     * @return \Api\PhpUtils\Mysql\MysqlBase
     */
    public static function searchList($params)
    {
        $lifeAccountId = MarketingService::getPublicLifeAccountId();
        $keywords = $params['keywords'] ?? '';
        $takePlaceIds = $params['take_place_id'] ?? [];
        $tagIds = isset($params['tag_ids']) ? $params['tag_ids'] : [];
        $businessCircleIds = $params['business_circle_ids'] ?? [];
        $offset = $params['offset'] ?? 0;
        $limit = $params['limit'] ?? 20;

        if (!empty($takePlaceIds)) {
            $where['take_place_id'] = $takePlaceIds;
        }
        if ($lifeAccountId) {
            $where['life_account_id'] = $lifeAccountId;
        }

        //处理 tag_ids = ['0'] 的情况
        if (count($tagIds) == 1 && $tagIds[0] == 0) {
            $tagIds = 0;
        }
        if ($tagIds || $tagIds == 0) {
            $where['tag_id'] = $tagIds;
        }
        if ($businessCircleIds) {
            $where['business_circle_id'] = $businessCircleIds;
        }
        if ($keywords) {
            $where['OR'] = [
                'take_place_name[~]' => $keywords,
                'contact_name[~]' => $keywords,
            ];
        }
        $where['is_delete'] = TakePlace::STATUS_NORMAL;
        $where['ORDER'] = ['take_place_id' => 'DESC'];
        $where['LIMIT'] = [$offset, $limit];

        $list = TakePlace::select('*', $where, []);
        $tagIds = array_unique(array_column($list, "tag_id"));
        $businessCircleIds = array_unique(array_column($list, "business_circle_id"));
        list ($tagArr, $businessCircleArr) = self::getTagAndBusinessCircle($tagIds, $businessCircleIds);
        $data = [];
        foreach ($list as $key => $item) {
            $data[$key] = $item;
            $data[$key]["tag_name"] = empty($tagArr[$item["tag_id"]]) ? "" : $tagArr[$item["tag_id"]]["tag_name"];
            $data[$key]["business_circle_name"] = empty($businessCircleArr[$item["business_circle_id"]]) ? "" : $businessCircleArr[$item["business_circle_id"]]["business_circle_name"];
        }
        $res['list'] = $data;
        unset($where['ORDER'], $where['LIMIT']);
        $res['total'] = TakePlace::count('*', $where);

        return $res;
    }

    /**
     * 获取某个自提点详情
     * 有删除自提点的情况，订单获取自提点详情时忽略自提点状态直接按id获取
     * @param $takePlaceId
     * @return \Api\PhpUtils\Mysql\MysqlBase
     */
    public static function detail($takePlaceId)
    {
        $takePlace = TakePlace::get('*', ['take_place_id' => $takePlaceId], []);
        $takePlace["tag_name"] = "";
        if (!empty($takePlace["tag_id"])) {
            $tag = TagService::tagDetail(["tag_id" => $takePlace["tag_id"]]);
            $takePlace["tag_name"] = $tag["tag_name"];
        }
        $takePlace["business_circle_name"] = "";
        if (!empty($takePlace["business_circle_id"])) {
            $businessCircle = BusinessCircleService::businessCircleDetail(["business_circle_id" => $takePlace["business_circle_id"]]);
            $takePlace["business_circle_name"] = $businessCircle["business_circle_name"];
        }

        return $takePlace;
    }

    /**
     * 批量获取自提点信息
     * @param $takePlaceIds
     * @return array
     */
    public static function getDetailByIds($takePlaceIds)
    {
        $result = TakePlace::select('*', ['take_place_id' => $takePlaceIds], []);
        $data = [];
        if (!empty($result)) {
            $tagIds = array_unique(array_column($result, "tag_id"));
            $businessCircleIds = array_unique(array_column($result, "business_circle_id"));
            list ($tagArr, $businessCircleArr) = self::getTagAndBusinessCircle($tagIds, $businessCircleIds);

            foreach ($result as $key => $item) {
                $data[$item["take_place_id"]] = $item;
                $data[$item["take_place_id"]]["tag_name"] = empty($tagArr[$item["tag_id"]]) ? "" : $tagArr[$item["tag_id"]]["tag_name"];
                $data[$item["take_place_id"]]["business_circle_name"] = empty($businessCircleArr[$item["business_circle_id"]]) ? "" : $businessCircleArr[$item["business_circle_id"]]["business_circle_name"];
            }
        }

        return $data;
    }

    /**
     * @param $tagIds
     * @param $businessCircleIds
     * @return array
     */
    private static function getTagAndBusinessCircle($tagIds, $businessCircleIds)
    {
        $tagArr = [];
        if (!empty($tagIds)) {
            $tagList = Tag::getRecords(["tag_id" => $tagIds], ["tag_id", "tag_name"]);
            if (!empty($tagList)) {
                $tagArr = array_column($tagList, null, "tag_id");
            }
        }

        $businessCircleArr = [];
        if (!empty($businessCircleIds)) {
            $businessCircleList = BusinessCircle::getRecords(["business_circle_id" => $businessCircleIds], ["business_circle_id", "business_circle_name"]);
            if (!empty($businessCircleList)) {
                $businessCircleArr = array_column($businessCircleList, null, "business_circle_id");
            }
        }

        return [$tagArr, $businessCircleArr];
    }

    /**
     * 添加自提点
     * @param $params
     * @return \Api\PhpUtils\Mysql\MysqlBase
     * @throws MarketingException
     */
    public static function add($params)
    {
        //验证life_account_id
        $lifeAccountId = MarketingService::getPublicLifeAccountId();
        if (isset($params['life_account_id']) && $params['life_account_id'] != $lifeAccountId) {
            $url = config('interface', 'merchant.lifeaccount.get_life_account_by_id');
            $lifeAccountRes = (new Request())->get($url, ["life_account_id" => $params["life_account_id"]]);

            if (empty($lifeAccountRes["response"]["result"])) {
                throw new MarketingException(['cus' => MarketingException::LIFE_ACCOUNT_NO_EXIST]);
            }
        }

        $data['life_account_id'] = $params['life_account_id'] ?? $lifeAccountId;
        $data['take_place_name'] = $params['name'];
        $data['take_place_pic'] = $params['take_place_pic'] ?? '';
        $data['longitude'] = $params['longitude'];
        $data['latitude'] = $params['latitude'];
        $data['location'] = $params['location'];
        $data['address'] = $params['address'];
        $data['contact_name'] = $params['contact_name'] ?? '';
        $data['phone'] = $params['phone'] ?? '';
        $data['province'] = $params['province'];
        $data['city'] = $params['city'];
        $data['area'] = $params['area'];
        $data['tag_id'] = empty($params['tag_id']) ? 0 : $params['tag_id'];
        $data['business_circle_id'] = empty($params['business_circle_id']) ? 0 : $params['business_circle_id'];
        $data['lunch_deliver_time'] = empty($params['lunch_deliver_time']) ? null : $params['lunch_deliver_time'];

        return TakePlace::insert($data);
    }

    /**
     * 删除自提点
     * @param $takePlaceId
     * @return \Api\PhpUtils\Mysql\MysqlBase
     * @throws MarketingException
     */
    public static function delete($takePlaceId)
    {
        if (empty(self::detail($takePlaceId))) {
            throw new MarketingException(['cus' => MarketingException::TAKE_PLACE_NOT_EXIST]);
        }
        return TakePlace::update(
            ['is_delete' => TakePlace::STATUS_DELETE],
            ['take_place_id' => $takePlaceId]
        );
    }

    /**
     * 给拼单活动绑定自提点
     * @param $marketingPindanId
     * @param $takePlaceId
     * @return \Api\PhpUtils\Mysql\MysqlBase
     * @throws MarketingException
     */
    public static function bindPindanTakePlace($marketingPindanId, $takePlaceId)
    {
        $data = [
            'marketing_pindan_id' => $marketingPindanId,
            'take_place_id' => $takePlaceId,
        ];

        //检查关联是否已存在
        if (!empty(MarketingTakePlace::get('*', $data))) {
            throw new MarketingException(['cus' => MarketingException::RELATION_ALREADY_EXIST]);
        }

        return MarketingTakePlace::insert($data);
    }

    /**
     * 获取拼单活动绑定的自提点列表
     * @param $params
     * @return array
     */
    public static function getPindanTakePlaceList($params)
    {
        $marketingId = $params['marketing_id'];
        $keywords = $params['keywords'] ?? '';
        $longitude = $params['longitude'] ?? '';
        $latitude = $params['latitude'] ?? '';
        $page = $params['page'] ?? 1;
        $limit = $params['limit'] ?? 20;

        //兼容客户端传递NaN字符串的问题
        if(!empty($longitude) && !is_numeric($longitude)) {
            $longitude = '';
        }
        if(!empty($latitude) && !is_numeric($latitude)) {
            $latitude = '';
        }
        //经纬度小程序调用时前后端都是反的，客户端按正确顺序传，程序把参数反过来，小程序目前来不及改，暂时先按反着的来
        //临时交换客户端传过来的经纬度的值 @todo 后期前后端一起修正传参后去掉此逻辑（注意小程序版本控制）
        if(isset($params['appid']) && $params['appid'] == 'merchant-c') {
            list($longitude,$latitude) = [$latitude,$longitude];
        }

        $offset = ($page-1)*$limit;
        $res = ['list'=>[],'total'=>0];

        $where = ['marketing_id' => $marketingId];

        if ($keywords) {
//            $where['OR'] = [
//                'take_place_name[~]' => $keywords,
//                'address[~]' => $keywords,
//            ];
            $where += [
                'take_place_name[~]' => $keywords,
            ];
        }
        $where['ORDER'] = ['marketing_take_place_id' => 'DESC'];

        // 如果分页后排序，排序就会有问题，自提点数量有限也不用分页处理。
//        $where['LIMIT'] = [$offset, $limit];

        $relations = MarketingTakePlace::select('*', $where);
        if (empty($relations)) {
            return $res;
        }
        //获取自提点信息
        $makePlaceIds = array_column($relations, 'take_place_id');
        $takePlaceWhere = ['take_place_id' => $makePlaceIds];

        if (!isset($params['has_delete'])) {
            $takePlaceWhere['is_delete'] = 0;
        }

        //本页按距离返回列表
        $list = self::sortByDistance($latitude, $longitude, TakePlace::select('*', $takePlaceWhere));

        $tagIds = array_unique(array_column($list, "tag_id"));
        $businessCircleIds = array_unique(array_column($list, "business_circle_id"));
        list ($tagArr, $businessCircleArr) = self::getTagAndBusinessCircle($tagIds, $businessCircleIds);
        $data = [];
        foreach ($list as $key => $item) {
            $data[$key] = $item;
            $data[$key]["tag_name"] = empty($tagArr[$item["tag_id"]]) ? "" : $tagArr[$item["tag_id"]]["tag_name"];
            $data[$key]["business_circle_name"] = empty($businessCircleArr[$item["business_circle_id"]]) ? "" : $businessCircleArr[$item["business_circle_id"]]["business_circle_name"];
        }
        $res['list'] = $data;


        unset($where['ORDER'], $where['LIMIT']);
        $res['total'] = MarketingTakePlace::count('*', $where);
        $res['total_page'] = ceil($res['total'] / $limit);

        return $res;
    }

    /**
     * 根据经纬度按距离排序
     * @param $lat
     * @param $lng
     * @param $list
     * @return array
     */
    private static function sortByDistance($lat, $lng, $list)
    {
        //未传经纬度
        if (empty($lat) || empty($lng)) {
            return $list;
        }
        //按距离返回自提点列表
        $sort = [];
        if (!empty($list) && is_array($list)) {
            foreach ($list as &$item) {
                if ($item['longitude'] && $item['latitude']) {
                    $item['distance'] = Geo::geoDistance($lat, $lng, $item['longitude'], $item['latitude'], true);
                    $sort[] = $item['distance'];
                } else {
                    $item['distance'] = '';
                }
            }
            unset($item);
            //按距离排序
            array_multisort($sort, SORT_ASC, $list);

            return $list;
        }
    }

}