<?php


namespace App\Services\marketing;

use Api\PhpUtils\Http\Request;
use App\Models\marketing\mysql\MarketingTakePlace;
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)
    {
        return TakePlace::searchList($params);
    }

    /**
     * 获取某个自提点详情
     * 有删除自提点的情况，订单获取自提点详情时忽略自提点状态直接按id获取
     * @param $takePlaceId
     * @return \Api\PhpUtils\Mysql\MysqlBase
     */
    public static function detail($takePlaceId)
    {
        return TakePlace::get('*',['take_place_id'=>$takePlaceId]);
    }

    /**
     * 批量获取自提点信息
     * @param $takePlaceIds
     * @return \Api\PhpUtils\Mysql\MysqlBase
     */
    public static function getDetailByIds($takePlaceIds)
    {
        $result = TakePlace::select('*',['take_place_id'=>$takePlaceIds]);
        return $result ? array_column($result,null,'take_place_id') : [];
    }

    /**
     * 添加自提点
     * @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'];

        return TakePlace::insert($data);
    }

    /**
     * 删除自提点
     * @param $takePlaceId
     * @return \Api\PhpUtils\Mysql\MysqlBase
     */
    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
     */
    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;

        $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;
        }

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

        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;
        }
    }

}