package com.bohuikeji.frame.module.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.TFranchiseeInformation;
import com.bohuikeji.frame.module.admin.mapper.TFranchiseeInformationMapper;
import com.bohuikeji.frame.module.admin.service.ITFranchiseeInformationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import com.bohuikeji.frame.module.admin.utils.MapUtils;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 加盟商信息表 服务实现类
 * </p>
 *
 * @author 10552
 * @since 2019-08-22
 */
@Slf4j
@Service
public class TFranchiseeInformationServiceImpl extends ServiceImpl<TFranchiseeInformationMapper, TFranchiseeInformation> implements ITFranchiseeInformationService {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ITFranchiseeInformationService informationService;

    @Override
    public TFranchiseeInformation getById(Serializable id){
        TFranchiseeInformation fran= redisUtil.get("sys:cache:fran:"+id.toString(),TFranchiseeInformation.class);
        if (fran==null){
            fran=super.getById(id);
            redisUtil.set("sys:cache:fran:"+id,fran,60*60);
        }
        return fran;
    }

    /**
     * 给定一个地理位置判断所在加盟商，如存在等级关系，返回最小级别，符合条件多个平级加盟商则返回第一个
     * @param address
     * @return
     */
    @Override
    public TFranchiseeInformation checkPio(AddressVo address) {
        String adcode=address.getAdcode();
        if("重庆市".equals(address.getCity())){
            if("铜梁区".equals(address.getArea())){
                log.error("地区编码空位1，根据经纬度查询地址信息返回加盟商。加盟商Id：[{}]",52);
                return getById(52);
            }else {
                log.error("地区编码空位2，根据经纬度查询地址信息返回加盟商。加盟商Id：[{}]",370);
                return getById(370);
            }
        }
        if(StringUtils.isBlank(adcode)){
            String location = address.getLng()+","+address.getLat();
            Integer franId = informationService.checkPio(MapUtils.getAddressReGeo(location)).getFranId();
            log.error("地区编码空位，根据经纬度查询地址信息返回加盟商。加盟商Id：[{}]",franId);
            return getById(franId);
        }
        //先判断区级以下的
        /*List<TFranchiseeInformation> franList=list(
                new QueryWrapper<TFranchiseeInformation>()
                        .eq("fran_service_adcode",adcode)
                        .isNotNull("fran_service_polyline"));
        TFranchiseeInformation fran=smallArea(franList,address);*/
        List<TFranchiseeInformation> franList=list(
                new QueryWrapper<TFranchiseeInformation>()
                        .eq("fran_service_adcode",adcode).eq("fran_status","启用"));
        if(franList.size()==1){
            return franList.get(0);
        }
        //
        /*if(fran==null){
            //获取区级
            fran= getOne(
                    new QueryWrapper<TFranchiseeInformation>()
                            .eq("fran_service_adcode",adcode)
                            .isNull("fran_service_polyline"));
            log.info("获取区级：[{}]",adcode);
        }*/
        //if(fran==null){
            //获取市级别
                TFranchiseeInformation fran=getOne(
                    new QueryWrapper<TFranchiseeInformation>()
                            .eq("fran_service_adcode",adcode.substring(0,4)+"00").eq("fran_status","启用"),false);
            //log.info("获取市级别：[{}]",adcode.substring(0,4)+"00");
        //}
        if(fran==null){
            //获取省
            fran=getOne(
                    new QueryWrapper<TFranchiseeInformation>()
                            .eq("fran_service_adcode",adcode.substring(0,2)+"0000").eq("fran_status","启用"),false);
            //log.info("获取省：[{}]",adcode.substring(0,2)+"0000");
        }
        if(fran==null){
            //全都没有设置为平台
            return getById(1);
        }
        return fran;
    }

    /**
     * 区级以下使用地理围栏识别
     * @param address
     * @return
     */
    private TFranchiseeInformation smallArea(List<TFranchiseeInformation> franList,AddressVo address){
                 for(TFranchiseeInformation fran:franList){
            String gid=fran.getFranServiceGid();
            //未创建地理围栏,或地理围栏失效，则重新生成地理围栏
            if(StringUtils.isBlank(gid)||(!MapUtils.checkGid(gid))){
                gid=MapUtils.createGid(fran.getFranServicePolyline());
                fran.setFranServiceGid(gid);
                fran.updateById();
            }
            //范围内直接返回
            if(StringUtils.isNotBlank(gid)&&MapUtils.checkPoint(gid,address.getLng(),address.getLat())){
                return fran;
            }
        }
        return null;
        /*log.error("无法找到该地址所属的加盟商，设置为平台，地址：[{}]",address);
        return getById(1);*/
    }

    /**
     * 查询下级加盟商列表
     * @return
     */
    @Override
    public Object[] queryLow(Integer id){
        String code=getObj(new QueryWrapper<TFranchiseeInformation>().select("fran_service_adcode").eq("fran_id",id), Object::toString);
        List<Object> ids=new ArrayList<Object>();
        //先查询市级别
        if(StringUtils.isNotBlank(code) && "00".equals(code.substring(4,6))){
            ids.addAll(listObjs(new QueryWrapper<TFranchiseeInformation>().eq("left(fran_service_adcode,4)",code.substring(0,4))));
        }
        //在查询区级别
        if("0000".equals(code.substring(2,6))){
            ids.addAll(listObjs(new QueryWrapper<TFranchiseeInformation>().eq("left(fran_service_adcode,2)",code.substring(0,2))));
        }
        ids.add(id);
        log.info("ids{}",ids);
        return ids.toArray(new Object[ids.size()]);
    }

    /**
     * 查询上级加盟商ID集合
     *
     * @param id
     * @return 返回上级加盟商ID数组+本加盟商ID
     */
    @Override
    public Object[] querySuper(Integer id) {
        //获取自己的地区code
        String code=getObj(new QueryWrapper<TFranchiseeInformation>().select("fran_service_adcode").eq("fran_id",id), Object::toString);
        List<Object> ids=new ArrayList<Object>();
        ids.add(id);
        //如果自己是城市一级别的，则省级别
        if("00".equals(code.substring(4,6))){
            //查询省级别
            ids.addAll(listObjs(new QueryWrapper<TFranchiseeInformation>().eq("fran_service_adcode",code.substring(0,2)+"0000")));
        }
        else {
            //查询市级别
            ids.addAll(listObjs(new QueryWrapper<TFranchiseeInformation>().eq("fran_service_adcode",code.substring(0,4)+"00")));
        }
        return ids.toArray(new Object[ids.size()]);
    }

    /**
     * 获取上级加盟商，顶级加盟商为平台
     *
     * @param id
     * @return
     */
    @Override
    public TFranchiseeInformation getSuper(Integer id) {
        TFranchiseeInformation superFran=redisUtil.get("sys:cache:super:fran:"+id,TFranchiseeInformation.class);
        if (superFran!=null){
            return superFran;
        }
        TFranchiseeInformation sonFran=getById(id);
        //无效加盟商直接返回平台
        if (sonFran!=null){
            Integer superId=sonFran.getSuperId();
            if (superId!=null&&superId>0){
                superFran=getById(superId);
                if (superFran!=null){
                    redisUtil.set("sys:cache:super:fran:"+id,sonFran,60*60*24*7);
                    return superFran;
                }
            }
            //如果自己是城市一级别的，则省级别
            if("00".equals(sonFran.getFranServiceAdcode().substring(4,6))){
                redisUtil.set("sys:cache:super:fran:"+id,sonFran,60*60*24*7);
                //查询省级别
                return getOne(new QueryWrapper<TFranchiseeInformation>().eq("fran_service_adcode",sonFran.getFranServiceAdcode().substring(0,2)+"0000"));
            }
            if("0000".equals(sonFran.getFranServiceAdcode().substring(2,6))){
                redisUtil.set("sys:cache:super:fran:"+id,sonFran,60*60*24*7);
                return getOne(new QueryWrapper<TFranchiseeInformation>().eq("fran_service_adcode",sonFran.getFranServiceAdcode().substring(0,4)+"00"));
            }
        }
        sonFran=getById(1);
        redisUtil.set("sys:cache:super:fran:1",sonFran,-1);
        return sonFran;
    }

}
