package com.zfire.jiasm.syncdata.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zfire.jiasm.syncdata.constant.Constant;
import com.zfire.jiasm.syncdata.constant.DictTypeEnum;
import com.zfire.jiasm.syncdata.constant.InterFaceTypeEnum;
import com.zfire.jiasm.syncdata.constant.OrderTypeEnum;
import com.zfire.jiasm.syncdata.dao.mapper.OJTGUploadTaskListMapper;
import com.zfire.jiasm.syncdata.parameter.InstallUpdatePar;
import com.zfire.jiasm.syncdata.plus.entity.*;
import com.zfire.jiasm.syncdata.plus.service.*;
import com.zfire.jiasm.syncdata.response.*;
import com.zfire.jiasm.syncdata.service.PublicService;
import com.zfire.jiasm.syncdata.test;
import com.zfire.jiasm.syncdata.utils.MyBeanUtils;
import com.zfire.jiasm.syncdata.utils.RedisUtil;
import com.zfire.jiasm.syncdata.utils.ResponseHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PublicServiceImpl implements PublicService {
    @Value("${lbs.web.key}")
    private String lbsWebKey;

    private static String ALISMS_NOHEARD = "尊敬的顾客您好，我司于%s接到您的工单信息，期间联系您的电话无人接听，如有需要可致电网点%s，网点服务热线%s，我司将竭诚为您服务，祝您生活愉快！";

    @Resource
    OrderWorkerService orderWorkerService;
    @Resource
    SysDictRefService sysDictRefService;
    @Resource
    WebsitOrderSignService websitOrderSignService;
    @Resource
    CustomerInformationWebsitService customerInformationWebsitService;
    @Resource
    BrandWebsitService brandWebsitService;
    @Resource
    WebsitService websitService;
    @Resource
    OutJiasmToGreeUploadTaskListService outJiasmToGreeUploadTaskListService;
    @Resource
    OJTGUploadTaskListMapper ojtgUploadTaskListMapper;
    @Resource
    OrderRepairOperatingLogService orderRepairOperatingLogService;
    @Resource
    SysDictService sysDictService;
    @Resource
    WebsitServiceCategoryDetailService websitServiceCategoryDetailService;
    @Resource
    BrandService brandService;
    @Resource
    ItfMessagehuifangentityService itfMessagehuifangentityService;
    @Resource
    SmsRecordService  smsRecordService;
    @Resource
    FaOrderSmsService faOrderSmsService;
    @Resource
    OrderBaseService orderbaseService;
    @Resource
    WorkerBrandAccountService workerBrandAccountService;
    @Resource
    WorkerService workerService;
    @Autowired
    SysVariableConfigService sysVariableConfigService;
    @Autowired
    SatisfactionListService satisfactionListService;
    @Autowired
    RedisUtil redis;
    @Resource
    ItfTblWangdianWxgDownloadService itfTblWangdianWxgDownloadService;
    @Resource
    StreetService streetService;
    @Resource
    AreaService areaService;
    @Resource
    BrandLbsRelateService brandLbsRelateService;
    @Autowired
    LbsAmapService lbsAmapService;


    private static String ALISMS_RESERVE = "尊敬的客户，您好！师傅上门时间为%s，服务网点电话：%s，如本次上门时间与您的安排有冲突，请拨打服务网点电话联系，我们将竭诚为您服务！";



    @Override
    public OrderWorker getOrderWorker(OrderBase orderBase){
        if (StringUtils.isNotEmpty(orderBase.getWorkerName())){
            OrderWorker orderWorker = getWorkerInfo(orderBase);
            if (orderWorker !=null){
                orderWorkerService.save(orderWorker);
                return orderWorker;
            }
        }
        return null;
    }

    @Override
    public OrderWorker getOrderWorkerApi(OrderBase orderBase){
        if (StringUtils.isNotEmpty(orderBase.getWorkerName())){
            return getWorkerInfo(orderBase);
        }

        return null;
    }

    private OrderWorker getWorkerInfo(OrderBase orderBase) {
        OrderWorker orderWorker = new OrderWorker();
        orderWorker.setOrderBaseId(orderBase.getId());
        orderWorker.setWorkerId(orderBase.getWorkerId());
        orderWorker.setWorkerName(orderBase.getWorkerName());
        orderWorker.setWorkerMobile(orderBase.getWorkerMobile());
        orderWorker.setWorkerIdcard(orderBase.getWorkerIdcard());
        orderWorker.setIsMaster(Boolean.TRUE);
        orderWorker.setBrandPgid(orderBase.getPgid());
        orderWorker.setPgguid(orderBase.getPgguid());
        orderWorker.setCreateTime(orderBase.getCreateTime());
        orderWorker.setCreateBy(orderBase.getCreateBy());
        orderWorker.setOutWorkerSource(Boolean.FALSE);
        return orderWorker;
    }

    @Override
    public List<OrderWorker> getWorker(String workerId,String orderBaseId) {
        List<OrderWorker> ows = orderWorkerService.lambdaQuery()
                .eq(OrderWorker::getOrderBaseId,orderBaseId)
                .eq(OrderWorker::getOutWorkerSource,Boolean.FALSE)
                .eq(OrderWorker::getIsMaster,Boolean.TRUE).list();
        return ows;
    }

    @Override
    public void deleteWorker(String orderBaseId){
        QueryWrapper del = new QueryWrapper<OrderWorker>()
                .eq("order_base_id", orderBaseId);

        orderWorkerService.remove(del);
    }


    @Override
    public Map<String, List<SysDictRef>> getStringListMap(Brand brand){
        List<SysDictRef> sysDictRef;
        Map<String, List<SysDictRef>> sysDictRefDLMap = new HashMap<>();
        sysDictRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_MAIN_TYPE.getCode())
                .list();
        sysDictRefDLMap = sysDictRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));
        return sysDictRefDLMap;
    }

    @Override
    public Map<String, List<SysDictRef>> getListMap(Brand brand){
        List<SysDictRef> sysDictxlRef;
        Map<String, List<SysDictRef>> sysDictRefXLMap = new HashMap<>();
        sysDictxlRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_SMALL_TYPE.getCode())
                .list();
        sysDictRefXLMap = sysDictxlRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));
        return sysDictRefXLMap;
    }

    @Override
    public Map<String, List<SysDictRef>> getMap(Brand brand){
        List<SysDictRef> sysDictxilieRef;
        Map<String, List<SysDictRef>> sysDictRefXiLieMap = new HashMap<>();
        sysDictxilieRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_SERIES.getCode())
                .list();
        sysDictRefXiLieMap = sysDictxilieRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));
        return sysDictRefXiLieMap;
    }


    @Override
    public Map<String, List<SysDictRef>> getStringListMapXq(Brand brand){
        List<SysDictRef> sysDictRef;
        Map<String, List<SysDictRef>> sysDictRefDLMap = new HashMap<>();
        sysDictRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_DEMAND_TYPE.getCode())
                .list();
        sysDictRefDLMap = sysDictRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));
        return sysDictRefDLMap;
    }

    @Override
    public Map<String, List<SysDictRef>> getListMapXq(Brand brand){
        List<SysDictRef> sysDictxlRef;
        Map<String, List<SysDictRef>> sysDictRefXLMap = new HashMap<>();
        sysDictxlRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_DEMAND_SMALL_TYPE.getCode())
                .list();
        sysDictRefXLMap = sysDictxlRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));
        return sysDictRefXLMap;
    }

    // 提取品牌商对应的需求小类信息
    @Override
    public Map<String, List<SysDictRef>> getListMapXqtoPP(Brand brand){
        List<SysDictRef> sysDictxlRef;
        Map<String, List<SysDictRef>> sysDictRefXLMap = new HashMap<>();
        sysDictxlRef =  sysDictRefService.lambdaQuery()
                .select(SysDictRef::getDictCode,SysDictRef::getDictValue,SysDictRef::getRefDictCode)
                .eq(SysDictRef::getBrandId, brand.getBrandId())
                .eq(SysDictRef::getDictType, DictTypeEnum.DICT_TYPE_DEMAND_SMALL_TYPE.getCode())
                .list();
        sysDictRefXLMap = sysDictxlRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getDictCode));
        return sysDictRefXLMap;
    }

    // 提取品牌商对应的需求类别信息
    @Override
    public Map<String, List<SysDict>> getStringListMapXqLb(){
        Map<String, List<SysDict>> result = new HashMap<>();

        List<SysDict> sysDictxl = sysDictService.lambdaQuery()
                .select(SysDict::getDictCode,SysDict::getDictValue)
                .eq(SysDict::getDictType, DictTypeEnum.DICT_TYPE_DEMAND_ASK_CATEGORY.getCode())
                .list();

        result = sysDictxl.stream().
                collect(Collectors.groupingBy(SysDict::getDictCode));
        return result;
    }



    @Override
    public String getSHWDPhone(String websitNo){
        Websit websit = websitService.lambdaQuery()
                .eq(Websit::getWebsitId,websitNo)
                .last("limit 1")
                .one();
        if (websit != null){
            if (StringUtils.isNotEmpty(websit.getHotline())){
                return websit.getHotline();
            } else if (StringUtils.isNotEmpty(websit.getOfficePhone()))
                return websit.getOfficePhone();
        }
        return "";
    }

    private WebsitFWS WebsitToSH(String websitNo, String brandId){
        WebsitFWS resultData = new WebsitFWS();

        resultData.setWebsitId("");
        resultData.setWdmc("");
        resultData.setWdlxdh("");

        // 先从售后网点查
        WebsitOrderSign wos = websitOrderSignService.lambdaQuery()
                .eq(WebsitOrderSign::getBrandWebsitId, websitNo)
                .eq(WebsitOrderSign::getBrandId, brandId)
                .last("limit 1")
                .one();
        if (wos != null){
            resultData.setWebsitId(wos.getWebsitId());
        } else {
            CustomerInformationWebsit ciwx = customerInformationWebsitService.lambdaQuery()
                    .eq(CustomerInformationWebsit::getRefWebsitId, websitNo)
                    .eq(CustomerInformationWebsit::getBrandId, brandId)
                    .last("limit 1")
                    .one();
            if (ciwx !=null){
                resultData.setWebsitId(ciwx.getWebsitId());
            }
        }

        // 提取网点名称
        if (StringUtils.isNotEmpty(resultData.getWebsitId())){
            Websit websit = websitService.lambdaQuery()
                    .eq(Websit::getWebsitId,resultData.getWebsitId())
                    .last("limit 1")
                    .one();
            if (websit != null){
                resultData.setWdmc(websit.getWebsitName());
                if (StringUtils.isNotEmpty(websit.getHotline())){
                    resultData.setWdlxdh(websit.getHotline());
                } else if (StringUtils.isNotEmpty(websit.getOfficePhone()))
                    resultData.setWdlxdh(websit.getOfficePhone());
            }
        }

        return resultData;
    }

    // 商户网点对应品牌网点
    private WebsitPP WebsitToPP(String websitId, String brandId){
        WebsitPP resultData = new WebsitPP();

        resultData.setXtwdno("");
        resultData.setWdno("");
        resultData.setWdmc("");

        // 先从售后网点查
        WebsitOrderSign wos = websitOrderSignService.lambdaQuery()
                .eq(WebsitOrderSign::getWebsitId, websitId)
                .eq(WebsitOrderSign::getBrandId, brandId)
                .last("limit 1")
                .one();
        if (wos != null){
            resultData.setWdno(wos.getBrandWebsitId());
            resultData.setWdmc(wos.getBrandWebsitName());
        } else {
            // 查看销售网点
            CustomerInformationWebsit ciwx = customerInformationWebsitService.lambdaQuery()
                    .eq(CustomerInformationWebsit::getWebsitId, websitId)
                    .eq(CustomerInformationWebsit::getBrandId, brandId)
                    .last("limit 1")
                    .one();
            if (ciwx !=null){
                resultData.setWdno(ciwx.getRefWebsitId());
                resultData.setWdmc(ciwx.getRefWebsitName());
            }
        }

        // 提取系统网点编号
        if (StringUtils.isNotEmpty(resultData.getWdno())){
            BrandWebsit bw = brandWebsitService.lambdaQuery()
                    .eq(BrandWebsit::getBrandWebsitNumber, resultData.getWdno())
                    .eq(BrandWebsit::getGroupCompanyId, brandId)
                    .last("limit 1")
                    .one();
            if (bw != null){
                resultData.setXtwdno(bw.getSysWebsitNumber());
            }

        }

        return resultData;
    }


    @Override
    public OutJiasmToGreeUploadTaskList getUploadTaskListLog(String orderNo, String id, Date updateTime,
                                                             String itemTableName, String itemOrderType, int taskType) {
        // 提取目志的类型
        OrderRepairOperatingLog rlog = orderRepairOperatingLogService.lambdaQuery()
                .eq(OrderRepairOperatingLog::getId,id)
                .last("limit 1")
                .one();

        OutJiasmToGreeUploadTaskList add = new OutJiasmToGreeUploadTaskList();
        add.setUploadTaskType(taskType);
        add.setOrderNo(orderNo);
        add.setId(id);
        add.setTaskExtraInfo(rlog.getType());
        add.setTableName(itemTableName);
        add.setOrderType(itemOrderType);
        add.setSynReqTime(new Date());
        add.setUpdatetime(updateTime);
        return add;
    }

    @Override
    public OutJiasmToGreeUploadTaskList getUploadTaskList(String orderNo, String id, Date updateTime,
                                                          String itemTableName, String itemOrderType, int taskType) {
        OutJiasmToGreeUploadTaskList add = new OutJiasmToGreeUploadTaskList();
        add.setUploadTaskType(taskType);
        add.setOrderNo(orderNo);
        add.setId(id);
        add.setTableName(itemTableName);
        add.setOrderType(itemOrderType);
        add.setSynReqTime(new Date());
        add.setUpdatetime(updateTime);
        return add;
    }

    @Override
    public OutJiasmToGreeUploadTaskList getUploadTaskList(String orderNo, String id,
                                                          String itemTableName, String itemOrderType, int taskType) {
        OutJiasmToGreeUploadTaskList add = new OutJiasmToGreeUploadTaskList();
        add.setUploadTaskType(taskType);
        add.setOrderNo(orderNo);
        add.setId(id);
        add.setTableName(itemTableName);
        add.setOrderType(itemOrderType);
        add.setSynReqTime(new Date());
        return add;
    }

    @Override
    public String getfsma(String phone) {
        Random random = new Random(System.currentTimeMillis());
        String fsma="";


        // 同一用户最近两个月内产生的发送码不能相同 itfMessagehuifangentityService
        while (Boolean.TRUE){
            fsma = String.valueOf(random.nextInt(10000));
            if (fsma.length()<4){
                if (fsma.length()==3){
                    fsma = fsma + "9";
                } else if (fsma.length()==2){
                    fsma = fsma + "99";
                } else {
                    fsma = fsma + "`999";
                }
            }
            if (StringUtils.isEmpty(phone.trim())){
                break;
            }
            List<ItfMessagehuifangentity> r = itfMessagehuifangentityService.lambdaQuery()
                    .eq(ItfMessagehuifangentity::getSjid,phone)
                    .eq(ItfMessagehuifangentity::getFsma,fsma)
                    .ge(ItfMessagehuifangentity::getCrdt,stepMonth(new Date(),-2)).list();
            if (CollectionUtils.isEmpty(r)){
                break;
            }
        }

        return fsma;
    }

    @Override
    public Date stepMonth(Date sourceDate, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }

    @Override
    public void updateUploadTaskListStatus(String orderNo, Long synReqId,Integer synStatus,Integer uploadTaskType){
        OutJiasmToGreeUploadTaskList upoutgultl = new OutJiasmToGreeUploadTaskList();
        upoutgultl.setSynReqId(synReqId);
        upoutgultl.setSynStatus(synStatus);
        upoutgultl.setSynTime(new Date());
        outJiasmToGreeUploadTaskListService.updateById(upoutgultl);

        // 批量修改
        InstallUpdatePar request = new InstallUpdatePar();
        request.setOrderNo(orderNo);
        request.setUploadTaskType(uploadTaskType);
        request.setSynReqId(synReqId);
        ojtgUploadTaskListMapper.installUpdateuploadTaskList(request);
    }

    @Override
    public void updateUploadTaskListInfo(Long synReqId,String msg){
        OutJiasmToGreeUploadTaskList upoutgultl = new OutJiasmToGreeUploadTaskList();
        upoutgultl.setSynReqId(synReqId);
        upoutgultl.setSynTime(new Date());
        upoutgultl.setSynErrMsg(msg);
        outJiasmToGreeUploadTaskListService.updateById(upoutgultl);
    }

    @Override
    public void updateUploadTaskLisError(OutJiasmToGreeUploadTaskList ojtutl, String msg){
        ojtutl.setSynTime(new Date());
        ojtutl.setSynErrMsg("other");
        ojtutl.setSynTimes(ojtutl.getSynTimes()+1);

        if (msg!=null){
            if (msg.length()>255){
                ojtutl.setSynErrMsg(msg.substring(0,255));
            } else {
                ojtutl.setSynErrMsg(msg);
            }
        }
        ojtutl.updateById();
    }

    /**
     * 商户网点信息
     * @param websitNo  商户网点编号
     * @param type      商户网点类型(销售或售后)
     */
    @Override
    public WebsitSH merchantWebsitInfoX(String websitNo,String type){
        WebsitSH resultData = new WebsitSH();
        // 提取格力集团信息
        Brand brandRec = brandService.lambdaQuery().eq(Brand::getBrand,"格力")
                .last("limit 1")
                .one();

        if (StringUtils.isEmpty(websitNo)){
            return resultData;
        }

        BrandWebsit brandWebsit = brandWebsitService.lambdaQuery()
                .eq(BrandWebsit::getGroupCompanyId,brandRec.getBrandId())
                .eq(BrandWebsit::getType,type)
                .eq(BrandWebsit::getBrandWebsitNumber,websitNo)
                .last("limit 1")
                .one();

        if (brandWebsit !=null){
            resultData.setWdId(brandWebsit.getBrandWebsitNumber());
            resultData.setWdmc(brandWebsit.getBrandWebsitName());
            resultData.setBrandSysWebsitNumber(brandWebsit.getSysWebsitNumber());
        }

        return resultData;
    }


    /**
     * 商户销售网点对应平台销售网点
     * @param websitNo  商户销售网点编号
     * @param order  商户工单类别、商户工单类型
     * @return
     */
    @Override
    public WebsitFWS shxswdToptxswd(String websitNo, OrderBase order){
        WebsitFWS resultData = new WebsitFWS();
        if (StringUtils.isEmpty(websitNo)){
            return resultData;
        }
        // 提取平台的销售网点信息 无信息不处理
        List<CustomerInformationWebsit> cIWebsitList = customerInformationWebsitService.lambdaQuery()
                .eq(CustomerInformationWebsit::getRefWebsitId,websitNo).list();
        if (CollectionUtils.isNotEmpty(cIWebsitList)){
            if (cIWebsitList.size()==1){
                // 这里的网点编号也是平台的商户编号
                resultData.setWebsitId(cIWebsitList.get(0).getWebsitId());
                resultData.setBrandSysWebsitNumber(cIWebsitList.get(0).getRefSysWebsitNumber());
                getNameAndHotline(resultData);
                resultData.setBrandId(cIWebsitList.get(0).getBrandId());
                resultData.setBrandName(cIWebsitList.get(0).getBrandName());
                return resultData;
            }

            List<CustomerInformationWebsit> ciws = new ArrayList<>();
            // 看服务商销售网点是否服务工单大类
            for (CustomerInformationWebsit item:cIWebsitList){
                WebsitServiceCategoryDetail wosinfo = getWebCategory(item.getBrandId(),item.getWebsitId(),order.getMainId(),order.getOrderType());
                if (wosinfo !=null){
                    ciws.add(item);
                }
            }

            if (CollectionUtils.isEmpty(ciws)){
                return resultData;
            }
            if (ciws.size()==1){
                resultData.setWebsitId(ciws.get(0).getWebsitId());
                getNameAndHotline(resultData);
                resultData.setBrandId(ciws.get(0).getBrandId());
                resultData.setBrandName(ciws.get(0).getBrandName());
                resultData.setBrandSysWebsitNumber(ciws.get(0).getRefSysWebsitNumber());
                return resultData;
            }

            // 多网点时再进行位置过滤
            CustomerInformationWebsit ci = getCustomerInformationWebsit(websitNo,ciws);
            if (ci!=null){
                resultData.setWebsitId(ci.getWebsitId());
                getNameAndHotline(resultData);
                resultData.setBrandId(ci.getBrandId());
                resultData.setBrandName(ci.getBrandName());
                resultData.setBrandSysWebsitNumber(ci.getRefSysWebsitNumber());
                return resultData;
            }

        }
        return resultData;
    }

    /**
     * 商户售后网点对应平台售后网点
     * @param websitNo  商户售后网点编号
     * @param order 商户工单大类、商户工单类型
     * @return
     */
   @Override
   public WebsitFWS shshwdToptshwd(String websitNo, OrderBase order){
       WebsitFWS resultData = new WebsitFWS();
       long tid = Thread.currentThread().getId();

       log.info("商户售后网点到平台服务商网点：["+tid+"]["+websitNo+"]["+order.getMainId()+"]");

       if (StringUtils.isEmpty(websitNo)){
           return resultData;
       }

       // 提取商户售后网点对应的平台售后网点信息 存在一对多的关系
       List<WebsitOrderSign> wos = getWebsitOrderSign(websitNo);
       if (CollectionUtils.isNotEmpty(wos)){
           // 找到一条记录时取网点名称直接返回
           if (wos.size() == 1){
               MyBeanUtils.copyProperties(wos.get(0),resultData);
               /*resultData.setWebsitId(wos.get(0).getWebsitId());
               // 网点名称及服务热线
               getNameAndHotline(resultData);
               resultData.setBrandSysWebsitNumber(wos.get(0).getBrandSysWebsitNumber());
               // 结算主体
               resultData.setBrandId(wos.get(0).getBrandId());
               resultData.setBrandName(wos.get(0).getBrandName());*/
               MyBeanUtils.copyProperties(wos.get(0),resultData);
               getNameAndHotline(resultData);

               log.info("商户售后网点到平台服务商网点锁定结果：["+tid+"]["+resultData.getWebsitId()+"]");
               return resultData;
           }

           // 多记录时根据网点服务的产品大类是否满足订单的大类(category) 进行取舍
           WebsitOrderSign wost = websitCategory(websitNo,wos, order.getMainId(), tid,order.getOrderType());
           // 无对应关系先工单落表，不再对应
           if (wost != null){
               /*resultData.setWebsitId(wost.getWebsitId());
               getNameAndHotline(resultData);
               resultData.setBrandSysWebsitNumber(wost.getBrandSysWebsitNumber());
               resultData.setBrandId(wost.getBrandId());
               resultData.setBrandName(wost.getBrandName());*/
               MyBeanUtils.copyProperties(wos.get(0),resultData);
               getNameAndHotline(resultData);
           }
       } else {
           log.info("商户售后网点到平台服务商网点："+tid+"]["+websitNo+"]无对应关系");
       }
       return resultData;
   }

    /**
     * 平台销售网点对应商户销售网点
     * @param websitNo  平台销售网点编号
     * @param category  工单类别
     * @return
     */
    @Override
    public WebsitSH ptxswdToshxswd(String websitNo, String category){
        WebsitSH resultData = new WebsitSH();
        if (StringUtils.isEmpty(websitNo)){
            return resultData;
        }

        // 提取平台的销售网点信息 无信息不处理
        List<CustomerInformationWebsit> cIWebsitList = customerInformationWebsitService.lambdaQuery()
                .eq(CustomerInformationWebsit::getWebsitId,websitNo).list();
        if (CollectionUtils.isNotEmpty(cIWebsitList)){
            if (cIWebsitList.size()==1){
                return merchantWebsitInfoX(cIWebsitList.get(0).getRefWebsitId(),
                        InterFaceTypeEnum.XS_WEBSIT_TYPE.getCode());
            }
            // 看商户销售网点是否服务工单大类,找到即返回
            for (CustomerInformationWebsit item:cIWebsitList) {
                BrandWebsit bw = brandWebsitService.lambdaQuery()
                        .eq(BrandWebsit::getGroupCompanyId, item.getGroupCompanyId())
                        .eq(BrandWebsit::getSplb,category)
                        .eq(BrandWebsit::getBrandWebsitNumber, item.getRefWebsitId())
                        .last("limit 1")
                        .one();
                if (bw != null) {
                    return merchantWebsitInfoX(bw.getBrandWebsitNumber(),
                            InterFaceTypeEnum.XS_WEBSIT_TYPE.getCode());
                }
            }
        }

        return resultData;
    }

    /**
     * 平台售后网点对应商户售后网点
     * @param websitNo  平台售后网点编号
     * @param category  工单
     * @return
     */
    @Override
    public WebsitSH  ptshwdToshshwd(String websitNo, String category) {
        WebsitSH resultData = new WebsitSH();
        List<BrandWebsit> wosn = new ArrayList<>();

        if (StringUtils.isEmpty(websitNo)) {
            return resultData;
        }

        // 提取平台售后网点对应的商户售后网点信息 存在一对多的关系
        List<WebsitOrderSign> wos = new ArrayList<>();
        wos = websitOrderSignService.lambdaQuery()
                .eq(WebsitOrderSign::getWebsitId, websitNo)
                .list();

        if (CollectionUtils.isNotEmpty(wos)) {
            // 找到一条记录时直接返回
            if (wos.size() == 1) {
                return merchantWebsitInfoX(wos.get(0).getBrandWebsitId(),
                        InterFaceTypeEnum.SH_WEBSIT_TYPE.getCode());
            }

            // 多记录时根据商户网点服务的产品大类是否满足订单的大类(category) 进行取舍
            for (WebsitOrderSign item : wos) {
                BrandWebsit bw = brandWebsitService.lambdaQuery()
                        .eq(BrandWebsit::getSplb, category)
                        .eq(BrandWebsit::getBrandWebsitNumber, item.getBrandWebsitId())
                        .last("limit 1")
                        .one();
                if (bw != null) {
                    wosn.add(bw);
                }
            }
            // 这里一般是存在的
            if (wosn.size() == 0) {
                return resultData;
            }

            // 已做限制 同一个大类不会归属两个以上服务网点
            return merchantWebsitInfoX(wosn.get(0).getBrandWebsitNumber(),
                    InterFaceTypeEnum.SH_WEBSIT_TYPE.getCode());
        }

        return resultData;
    }


    /**
     * 向发送短信表添加数据 工单类型，短信类型
     * @return true写入成功，false写入失败
     */
    @Override
    public Boolean addSmsRecord(ItfMessagehuifangentity addms,String orderType,int type){
        SmsRecord record = new SmsRecord();
        // 插入前查看是否已存在，存在不再插入
        List<SmsRecord> sr = smsRecordService.lambdaQuery()
                .eq(SmsRecord::getOrderBaseId,addms.getOrderBaseId())
                .eq(SmsRecord::getOrderType,orderType)
                .eq(SmsRecord::getType,type)
                .eq(SmsRecord::getPhone,addms.getSjid())
                .eq(SmsRecord::getFsma,addms.getFsma()).list();
        if (CollectionUtils.isNotEmpty(sr)){
            return Boolean.TRUE;
        }

        // 生成实体对像
        getSmsRecord(addms, orderType, type, record);

        return smsRecordService.save(record);
    }

    // ID同预约改约表ID相同，方便查找
    private Boolean addSRecord(OrderReAppointment rea){
        // 插入前查看是否已存在，存在不再插入
        SmsRecord sr = smsRecordService.lambdaQuery()
                .eq(SmsRecord::getId,rea.getId())
                .last("limit 1")
                .one();
        if (sr !=null){
            return Boolean.TRUE;
        }

        // 新增发短信数据
        return addSmsRecord(rea);

    }

    @Override
    public Boolean addFaOrderSms(OrderReAppointment rea){
        OrderBase orderBase = orderbaseService.lambdaQuery()
                .eq(OrderBase::getId,rea.getOrderBaseId())
                .last("limit 1")
                .one();
        if (orderBase == null){
            return Boolean.TRUE;
        }
        // 一个工单只能有一次预约信息，改约可以多个
        if (rea.getFlag()==1){
            FaOrderSms r = faOrderSmsService.lambdaQuery()
                    .eq(FaOrderSms::getSynTaskNo,rea.getId())
                    .last("limit 1")
                    .one();
            if (r !=null){
                return Boolean.TRUE;
            }
        }

        // 生成预约改约短信实体对像
        FaOrderSms add = getFaOrderSms(orderBase, rea);
        // 插入发短信数据表
        if (faOrderSmsService.save(add)){
            // 预约改约同时向短信记录表同步数据
            return addSRecord(rea);
        }
        return Boolean.FALSE;
    }

    private FaOrderSms getFaOrderSms(OrderBase orderBase, OrderReAppointment rea) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        FaOrderSms add = new FaOrderSms();

        // add.setSynTaskNo(rea.getId());
        add.setWorkerOrderNo(orderBase.getId());
        // 工单类型 (1:安装,2:维修,3:回收工单,4:以旧换新)
        add.setAzorwx(4);
        // 工单类型 INSTALL=安装单  REPAIR=维修单  RETURN_EXCHANGE=退换货  TRADE_IN=以旧换新 MAINTENANCE=维保工单
        if (orderBase.getOrderType().equals(OrderTypeEnum.ORDER_TYPE_INSTALL.getCode())){
            add.setAzorwx(1);
        } else if (orderBase.getOrderType().equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
            add.setAzorwx(2);
        } else if (orderBase.getOrderType().equals(OrderTypeEnum.ORDER_TYPE_RECOVERY.getCode())){
            add.setAzorwx(3);
        }
        // 维修工单pgid 其他工单pggid
        if (orderBase.getOrderType().equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
            add.setFjid(orderBase.getPgid());
        } else {
            add.setFjid(orderBase.getPgguid());
        }
        add.setFjid(orderBase.getUserMobile());
        add.setFjwd(orderBase.getWebsitId());
        add.setFsma(getFaOrderSmsfsma(orderBase.getUserMobile()));
        add.setFsnr(String.format(ALISMS_NOHEARD,
                sdf.format(orderBase.getDispatchWebsitTime()),
                orderBase.getWebsitName(),
                getSHWDPhone(orderBase.getWebsitId())));
        add.setSjid(orderBase.getUserMobile());
        // 1:预约上门,4:改约
        add.setYhlb(4);
        if (rea.getFlag()==1){
            add.setYhlb(1);
        }

        return add;
    }

    /**
     * 根据经纬度反查省市区街道
     * @Param lng,lat
     * @Return {"area":"番禺区","province":"广东省","city":"广州市","street":"大龙街道"}
     */
    @Override
    public Geographicallocation getRegionByAddress(String lng, String lat){
        Geographicallocation result = new Geographicallocation();
        String lnglat = lng + "," + lat;
        String url = "https://restapi.amap.com/v3/geocode/regeo?key="+lbsWebKey+"&location="+lnglat;
        String s = HttpUtil.get(url);
        JSONObject jsonObject = new JSONObject(s);
        String status = jsonObject.getStr("status");
        if(!status.equals("1")){
            return null;
        }
        JSONObject regeocode = jsonObject.getJSONObject("regeocode");
        JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
        Map<String,String> map = new HashMap<>();
        result.setProvince(addressComponent.getStr("province"));
        if(addressComponent.getStr("city").equals("[]")) {
            result.setCity(addressComponent.getStr("province"));
        }else{
            result.setCity(addressComponent.getStr("city"));
        }
        if(addressComponent.getStr("district").equals("[]")) {
            result.setArea(addressComponent.getStr("city"));
        }else{
            result.setArea(addressComponent.getStr("district"));
        }
        result.setStreet(addressComponent.getStr("township"));
        return result;
    }

    // 根据地址反查经纬度
    @Override
    public String getLocationByAddress(String address){
        String url = "https://restapi.amap.com/v3/geocode/geo?key="+lbsWebKey+"&address="+address;
        String s = HttpUtil.get(url);
        JSONObject jsonObject = new JSONObject(s);
        String status = jsonObject.getStr("status");
        if(!status.equals("1")){
            return null;
        }
        JSONArray geocodes = jsonObject.getJSONArray("geocodes");
        if(org.springframework.util.CollectionUtils.isEmpty(geocodes))
            return null;
        Map<String, Object> map = (Map<String, Object>) geocodes.get(0);
        String location = (String)map.get("location");
        return location;
    }

    // 获取gpsaddress
    @Override
    public String getGpsaddress(String lng, String lat){
        String gps="";
        if (StringUtils.isNotEmpty(lng) && StringUtils.isNotEmpty(lat)){
            Geographicallocation result = getRegionByAddress(lng, lat);
            if (result !=null){
                gps=result.getProvince()+
                        result.getCity()+
                        result.getArea()+
                        result.getStreet();
            }
        }

        return gps;
    }

    // 商户网点编号    belongCompanyId(1:佛山,2:广州,3:天猫)
    @Override
    public Integer getCompanyId(String brandWebsitNumber){
        BrandWebsit bw = brandWebsitService.lambdaQuery()
                .eq(BrandWebsit::getBrandWebsitNumber, brandWebsitNumber)
                .last("limit 1")
                .one();
        if (bw != null){
            return bw.getBelongCompanyId();
        }
        return 1;
    }

    @Override
    public void getExpireTime(OrderBase orderBase, Date ssDate, Date jzDate) {
        int hour = 24;
        int hourjz = 24;
        Date d = new Date();

        // 提取配置参数 首次申诉-服务人员+网点审核截止时间
        SysVariableConfig config = sysVariableConfigService.lambdaQuery()
                .eq(SysVariableConfig::getVariableType,"APPEAL_TIME")
                .eq(SysVariableConfig::getSmallType,3)
                .last("limit 1")
                .one();
        if (config != null){
            hour = Integer.valueOf(config.getVariableValue());
        }

        hourjz = hour;
        // 应家盛茂平台要求只要短信发送时间，这里hour改成0；
        hour=0;
        // 提取短信发送时间 目的配合配置参数生成申诉单的截止申诉时间
        ItfMessagehuifangentity message = itfMessagehuifangentityService.lambdaQuery()
                .eq(ItfMessagehuifangentity::getOrderBaseId, orderBase.getId())
                .eq(ItfMessagehuifangentity::getFjid, orderBase.getPgguid())
                .last("limit 1")
                .one();


        // 测试时存在无message的情况
        if (message == null){
            if (orderBase.getOverTime()!=null){
                d = orderBase.getOverTime();
            }
            if (orderBase.getWebsitOverTime() !=null){
                d = orderBase.getWebsitOverTime();
            }
            ssDate.setTime(d.getTime()+ hour * 60 * 60 * 1000);
            jzDate.setTime(d.getTime()+ hourjz * 60 * 60 * 1000);
        } else {
            ssDate.setTime(message.getSendtime().getTime()+ hour * 60 * 60 * 1000);
            jzDate.setTime(message.getSendtime().getTime()+ hourjz * 60 * 60 * 1000);
        }
    }

    @Override
    public void getExpireTimeRepair(OrderBase orderBase, Date ssDate, Date jzDate) {
        int hour = 24;
        int hourjz = 24;
        Date d = new Date();

        // 提取配置参数 首次申诉-服务人员+网点审核截止时间
        SysVariableConfig config = sysVariableConfigService.lambdaQuery()
                .eq(SysVariableConfig::getVariableType,"APPEAL_TIME")
                .eq(SysVariableConfig::getSmallType,3)
                .last("limit 1")
                .one();
        if (config != null){
            hour = Integer.valueOf(config.getVariableValue());
        }

        hourjz = hour;
        // 应家盛茂平台要求只要短信发送时间，这里hour改成0；
        hour=0;
        // 提取短信发送时间 目的配合配置参数生成申诉单的截止申诉时间
        ItfMessagehuifangentity message = itfMessagehuifangentityService.lambdaQuery()
                .eq(ItfMessagehuifangentity::getOrderBaseId, orderBase.getId())
                .eq(ItfMessagehuifangentity::getFjid, orderBase.getPgid())
                .last("limit 1")
                .one();


        // 测试时存在无message的情况
        if (message == null){
            if (orderBase.getOverTime()!=null){
                d = orderBase.getOverTime();
            }
            if (orderBase.getWebsitOverTime() !=null){
                d = orderBase.getWebsitOverTime();
            }
            ssDate.setTime(d.getTime()+ hour * 60 * 60 * 1000);
            jzDate.setTime(d.getTime()+ hourjz * 60 * 60 * 1000);
        } else {
            ssDate.setTime(message.getSendtime().getTime()+ hour * 60 * 60 * 1000);
            jzDate.setTime(message.getSendtime().getTime()+ hourjz * 60 * 60 * 1000);
        }
    }

    // 返回差评标识
    // SATISFACTION=好GENERAL=中DISPLEASURE=差 ELIMINATE=剔除 OTHER_APPRISE=其他
    @Override
    public Boolean  checkEvaluatemessage(String pjly){
        SatisfactionList sfl = satisfactionListService.lambdaQuery()
                .eq(SatisfactionList::getPjly,pjly.trim())
                .last("limit 1")
                .one();
        if (sfl==null){
            return Boolean.TRUE;
        }
        if (sfl.getAppraiseType().equals("SATISFACTION")){
            return Boolean.FALSE;
        } else {
            return Boolean.TRUE;
        }
    }

    @Override
    public SatisfactionList  getAppraiseStatus(String pjly){
        List<SatisfactionList> rec = satisfactionListService.lambdaQuery()
                .eq(SatisfactionList::getPjly,pjly.trim()).list();
        if (CollectionUtils.isNotEmpty(rec)){
            return rec.get(0);
        }

        return null;
    }

    // 获取安装工单对应的师傅信息
    @Override
    public Worker getInstallOrderWorker(Long azrenid){
        List<Worker> worker = new ArrayList<>();
        ItfTblWangdianWxgDownload wdwxg = itfTblWangdianWxgDownloadService.lambdaQuery()
                .eq(ItfTblWangdianWxgDownload::getWxgid,azrenid)
                .last("limit 1")
                .one();
        // 根据身份证取师傅信息
        if (wdwxg !=null){
            worker = workerService.lambdaQuery()
                    .eq(Worker::getIdcard,wdwxg.getSfzen()).list();
            if (CollectionUtils.isNotEmpty(worker)){
                return worker.get(0);
            }
        }
        return null;
    }


    // SATISFACTION=好GENERAL=中DISPLEASURE=差 ELIMINATE=剔除 OTHER_APPRISE=其他
    // 评价状态 A=满意  B=一般  C=不满意
    @Override
    public String checkAppraiseType(String pjly){
        String result ="C";
        SatisfactionList sfl = satisfactionListService.lambdaQuery()
                .eq(SatisfactionList::getPjly,pjly.trim())
                .last("limit 1")
                .one();
        if (sfl==null){
            result = "C";
        } else {
            if (sfl.getAppraiseType().equals("SATISFACTION")){
                result = "A";
            } else if (sfl.getAppraiseType().equals("GENERAL")){
                result = "B";
            }
        }

        return result;
    }

    @NotNull
    @Override
    public String getErrormessage(ResponseHelper respone) {
        String redisKey = Constant.RedisPrefix.TOKEN_JIASM_ORDER;
        // 签名验证失败处理
        if (respone.getCode()==1001){
            redis.del(redisKey);
        } else if (respone.getMessage()!=null && respone.getMessage().indexOf("签名验证失败")>=0){
            redis.del(redisKey);
        }

        String msg ="";
        if (respone.getMessage()!=null){
            msg=msg+ respone.getMessage();
        }
        return msg;
    }


    // 获取师傅在商户网点账号 平台师傅账号，商户网点编号，集团ID
    @Override
    public Long getBrandWorkerId(String workerId,String brandWebsitId,String groupCompanyId, String websitId){
        long brandWorkerId =0;

        WorkerBrandAccount wba = workerBrandAccountService.lambdaQuery()
                .eq(WorkerBrandAccount::getGroupCompanyId,groupCompanyId)
                .eq(WorkerBrandAccount::getBrandWorkerStatus,"ON")
                .eq(WorkerBrandAccount::getDel,0)
                .eq(WorkerBrandAccount::getWorkerId,workerId)
                .eq(WorkerBrandAccount::getBrandWebsitId,brandWebsitId)
                .eq(WorkerBrandAccount::getWebsitId,websitId)
                .last("limit 1")
                .one();
        if (wba !=null){
            if (StringUtils.isNotEmpty(wba.getBrandWorkerId())){
                return Long.valueOf(wba.getBrandWorkerId());
            }
        }

        return brandWorkerId;
    }

    @Override
    public WorderInfo getWorkerInfo(String workerId,String brandWebsitId,String groupCompanyId){
        WorderInfo info = new WorderInfo();
        WorkerBrandAccount wba = workerBrandAccountService.lambdaQuery()
                .eq(WorkerBrandAccount::getGroupCompanyId,groupCompanyId)
                .eq(WorkerBrandAccount::getBrandWorkerStatus,"ON")
                .eq(WorkerBrandAccount::getDel,0)
                .eq(WorkerBrandAccount::getWorkerId,workerId)
                .eq(WorkerBrandAccount::getBrandWebsitId,brandWebsitId)
                .last("limit 1")
                .one();
        if (wba !=null){
            MyBeanUtils.copyProperties(wba,info);
            Worker wk = workerService.lambdaQuery()
                    .eq(Worker::getWorkerId,workerId)
                    .last("limit 1")
                    .one();

            MyBeanUtils.copyProperties(wk,info);
        }

        return info;
    }

    @Override
    public List<WebsitOrderSign> SyncshshwdToptshwd(){
        // 提取商户售后网点对应的平台售后网点信息 存在一对多的关系
        List<WebsitOrderSign> wos = new ArrayList<>();
        wos = websitOrderSignService.lambdaQuery().list();
        return wos;
    }


    // 安装工单的省市区对应关系
    @Override
    public void installOrderSSQJ(OrderBase orderBase){
        // 先查 lbs_amap表 1省，2市，3区，4街道 找到直接返回
        Integer flag = getLbsAmap(orderBase);
        if (flag>3){
            return;
        }

        // 再查 BrandLbsRelate 表
        getBrandLbsRelate(orderBase,flag);

        // 根据地址设置经纬度
        setLocationByAddress(orderBase);
    }

    private void setLocationByAddress(OrderBase orderBase) {
        if (StringUtils.isEmpty(orderBase.getLng()) || StringUtils.isEmpty(orderBase.getLat())) {
            String add = "";
            if (StringUtils.isNotEmpty(orderBase.getProvince())) {
                add = add + orderBase.getProvince();
            }
            if (StringUtils.isNotEmpty(orderBase.getCity())) {
                add = add + orderBase.getCity();
            }
            if (StringUtils.isNotEmpty(orderBase.getArea())) {
                add = add + orderBase.getArea();
            }
            if (StringUtils.isNotEmpty(orderBase.getStreet())) {
                add = add + orderBase.getStreet();
            }
            if (StringUtils.isEmpty(add)) {
                return;
            }
            String lngLat = getLocationByAddress(add);
            if (StringUtils.isEmpty(lngLat)) {
                return;
            }
            List<String> result = Arrays.asList(lngLat.split(","));

            orderBase.setLng(result.get(0));
            orderBase.setLat(result.get(1));
        }
    }

    private void getBrandLbsRelate(OrderBase orderBase, Integer flag) {
        // 格力总部的省市区为必填，可能无街道
        if (StringUtils.isNotEmpty(orderBase.getStreet())){
            // 提取格力总部的省市区街道信息  这里带上街道条件，可能查不到
            Street street = streetService.lambdaQuery()
                    .eq(Street::getStatus, 1)
                    .eq(Street::getProvince, orderBase.getProvince())
                    .eq(Street::getCity, orderBase.getCity())
                    .eq(Street::getArea, orderBase.getArea())
                    .eq(Street::getStreet, orderBase.getStreet())
                    .last("limit 1")
                    .one();
            // 对应出平台的省市区街道信息 无对应关系时依总部的为准
            if (street!=null){
                getPosition(orderBase, street, flag);
            } else {
                // 总部区必选项 按区再次查询
                List<Area> area = areaService.lambdaQuery()
                        .eq(Area::getProvince, orderBase.getProvince())
                        .eq(Area::getCity, orderBase.getCity())
                        .eq(Area::getArea, orderBase.getArea()).list();

                Street st = new Street();
                if (CollectionUtils.isNotEmpty(area)){
                    BeanUtils.copyProperties(area.get(0),st);
                    getPosition(orderBase, st, flag);
                    orderBase.setStreet("");
                }
            }
        } else {
            List<Area> area = areaService.lambdaQuery()
                    .eq(Area::getProvince, orderBase.getProvince())
                    .eq(Area::getCity, orderBase.getCity())
                    .eq(Area::getArea, orderBase.getArea()).list();
            Street st = new Street();
            if (CollectionUtils.isNotEmpty(area)){
                BeanUtils.copyProperties(area.get(0),st);
                getPosition(orderBase, st, flag);
                orderBase.setStreet("");
            }
        }


        // getLocationByAddress
        if (StringUtils.isEmpty(orderBase.getLng()) || StringUtils.isEmpty(orderBase.getLat())){
            String add = "";
            if (StringUtils.isNotEmpty(orderBase.getProvince())){
                add = add + orderBase.getProvince();
            }
            if (StringUtils.isNotEmpty(orderBase.getCity())){
                add = add + orderBase.getCity();
            }
            if (StringUtils.isNotEmpty(orderBase.getArea())){
                add = add + orderBase.getArea();
            }
            if (StringUtils.isNotEmpty(orderBase.getStreet())){
                add = add + orderBase.getStreet();
            }
            if (StringUtils.isEmpty(add)){
                return;
            }
            String lngLat = getLocationByAddress(add);
            if (StringUtils.isEmpty(lngLat)){
                return;
            }
            List<String> result = Arrays.asList(lngLat.split(","));

            orderBase.setLng(result.get(0));
            orderBase.setLat(result.get(1));
        }
    }

    // 1省，2市，3区，4街道
    private Integer getLbsAmap(OrderBase orderBase){
        // 先查 lbs_amap表
        LbsAmap lbsAmap = lbsAmapService.lambdaQuery()
                .eq(LbsAmap::getName,orderBase.getProvince())
                .eq(LbsAmap::getLevel,"province")
                .last("limit 1").one();
        if (lbsAmap == null){
            return 0;
        }
        //省
        orderBase.setProvinceId(lbsAmap.getProvinceId());
        orderBase.setProvince(lbsAmap.getProvinceName());

        lbsAmap = lbsAmapService.lambdaQuery()
                .eq(LbsAmap::getProvinceId,lbsAmap.getProvinceId())
                .eq(LbsAmap::getName,orderBase.getCity())
                .eq(LbsAmap::getLevel,"city")
                .last("limit 1").one();
        if (lbsAmap == null){
            return 1;
        }
        //市
        orderBase.setCityId(lbsAmap.getCityId());
        orderBase.setCity(lbsAmap.getCityName());

        lbsAmap = lbsAmapService.lambdaQuery()
                .eq(LbsAmap::getProvinceId,lbsAmap.getProvinceId())
                .eq(LbsAmap::getCityId,lbsAmap.getCityId())
                .eq(LbsAmap::getName,orderBase.getArea())
                .eq(LbsAmap::getLevel,"district")
                .last("limit 1").one();
        if (lbsAmap == null){
            return 2;
        }
        //区
        orderBase.setAreaId(lbsAmap.getAreaId());
        orderBase.setArea(lbsAmap.getAreaName());

        lbsAmap = lbsAmapService.lambdaQuery()
                .eq(LbsAmap::getProvinceId,lbsAmap.getProvinceId())
                .eq(LbsAmap::getCityId,lbsAmap.getCityId())
                .eq(LbsAmap::getAreaId,lbsAmap.getAreaId())
                .eq(LbsAmap::getName,orderBase.getStreet())
                .eq(LbsAmap::getLevel,"street")
                .last("limit 1").one();
        if (lbsAmap == null){
            return 3;
        }
        //街道
        orderBase.setStreetId(lbsAmap.getLbsId());
        orderBase.setStreet(lbsAmap.getName());

        return 4;
    }

    private void getPosition(OrderBase orderBase, Street street, Integer flag) {
        //省市区，有时无街道，这里不提取街道信息
        List<BrandLbsRelate> br = brandLbsRelateService.lambdaQuery()
                .eq(BrandLbsRelate::getDel,0)
                .eq(BrandLbsRelate::getProvinceId, street.getProvinceId())
                .eq(BrandLbsRelate::getCityId, street.getCityId())
                .eq(BrandLbsRelate::getAreaId, street.getAreaId())
                .isNotNull(BrandLbsRelate::getLbsProvinceId)
                .isNotNull(BrandLbsRelate::getLbsCityId)
                .isNotNull(BrandLbsRelate::getLbsDistrictId).list();

        if (br !=null && br.size()>0){
            if (flag==0){
                //省
                orderBase.setProvinceId(br.get(0).getLbsProvinceId());
                orderBase.setProvince(br.get(0).getLbsProvinceName());
                //市
                orderBase.setCityId(br.get(0).getLbsCityId());
                orderBase.setCity(br.get(0).getLbsCityName());
                //区
                orderBase.setAreaId(br.get(0).getLbsDistrictId());
                orderBase.setArea(br.get(0).getLbsDistrictName());
            } else if (flag==1){
                //市
                orderBase.setCityId(br.get(0).getLbsCityId());
                orderBase.setCity(br.get(0).getLbsCityName());
                //区
                orderBase.setAreaId(br.get(0).getLbsDistrictId());
                orderBase.setArea(br.get(0).getLbsDistrictName());
            } else if (flag==2){
                //区
                orderBase.setAreaId(br.get(0).getLbsDistrictId());
                orderBase.setArea(br.get(0).getLbsDistrictName());
            }
        } else {
            // 找不到依总部的为准
            if (StringUtils.isEmpty(orderBase.getProvinceId())){
                orderBase.setProvinceId(street.getProvinceId());
            }
            if (StringUtils.isEmpty(orderBase.getCityId())){
                orderBase.setCityId(street.getCityId());
            }
            if (StringUtils.isEmpty(orderBase.getAreaId())){
                orderBase.setAreaId(street.getAreaId());
            }
            if (StringUtils.isEmpty(orderBase.getStreetId())){
                orderBase.setStreetId(street.getStreetId());
            }
            if (StringUtils.isEmpty(orderBase.getStreet()) &&
                    StringUtils.isEmpty(street.getStreet())){
                orderBase.setStreet(street.getStreet());
            }
            return;
        }

        // 提取街道信息
        if (StringUtils.isNotEmpty(orderBase.getStreet())){
            //街道单独处理
            br = brandLbsRelateService.lambdaQuery()
                    .eq(BrandLbsRelate::getDel,0)
                    .eq(BrandLbsRelate::getProvinceId, street.getProvinceId())
                    .eq(BrandLbsRelate::getCityId, street.getCityId())
                    .eq(BrandLbsRelate::getAreaId, street.getAreaId())
                    .eq(BrandLbsRelate::getStreetId,street.getStreetId())
                    .isNotNull(BrandLbsRelate::getLbsProvinceId)
                    .isNotNull(BrandLbsRelate::getLbsCityId)
                    .isNotNull(BrandLbsRelate::getLbsDistrictId)
                    .isNotNull(BrandLbsRelate::getLbsStreetId).list();
            if (br !=null && br.size()>0){
                orderBase.setStreetId(br.get(0).getLbsStreetId());
                orderBase.setStreet(br.get(0).getLbsStreetName());
            }
        } else {
            // 先街道时依总部为准
            if (StringUtils.isEmpty(orderBase.getStreetId()) &&
                    StringUtils.isNotEmpty(street.getStreetId())){
                orderBase.setStreetId(street.getStreetId());
            }
            if (StringUtils.isEmpty(orderBase.getStreet()) &&
                    StringUtils.isNotEmpty(street.getStreet())){
                orderBase.setStreet(street.getStreet());
            }
        }
    }

    private String getFaOrderSmsfsma(String phone) {
        Random random = new Random(System.currentTimeMillis());
        String fsma="";
        // 同一用户最近两个月内产生的发送码不能相同
        while (Boolean.TRUE){
            fsma = String.valueOf(random.nextInt(10000));
            if (fsma.length()<4){
                if (fsma.length()==3){
                    fsma = fsma + "9";
                } else if (fsma.length()==2){
                    fsma = fsma + "99";
                } else {
                    fsma = fsma + "`999";
                }
            }
            List<FaOrderSms> r = faOrderSmsService.lambdaQuery()
                    .eq(FaOrderSms::getSjid,phone)
                    .eq(FaOrderSms::getFsma,fsma)
                    .ge(FaOrderSms::getCrdt,stepMonth(new Date(),-2)).list();
            if (CollectionUtils.isEmpty(r)){
                break;
            }
        }

        return fsma;
    }

    private Boolean addSmsRecord(OrderReAppointment rea) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SmsRecord record = new SmsRecord();

        record.setId(rea.getId());
        record.setOrderBaseId(rea.getOrderBaseId());
        record.setOrderType(rea.getOrderType());
        record.setType(4);
        if (rea.getFlag() == 1){
            record.setType(rea.getFlag());
        }

        record.setPhone(rea.getUserMobile());
        if (record.getType()==1){
            record.setContent(String.format(ALISMS_RESERVE,
                    sdf.format(rea.getOldAppointmentTime()),getSHWDPhone(rea.getWebsitId())));
        } else {
            record.setContent(String.format(ALISMS_RESERVE,
                    sdf.format(rea.getNewAppointmentTime()),getSHWDPhone(rea.getWebsitId())));
        }
        record.setFsma(getfsma(record.getPhone()));
        record.setCreateTime(new Date());

        return smsRecordService.save(record);
    }

    private void getSmsRecord(ItfMessagehuifangentity addms, String orderType, int type, SmsRecord record) {
        record.setId(UUID.randomUUID().toString());
        record.setOrderBaseId(addms.getOrderBaseId());
        record.setOrderType(orderType);
        record.setType(type);
        record.setPhone(addms.getSjid());
        record.setContent(addms.getFsnr());
        record.setFsma(addms.getFsma());
        record.setCreateTime(new Date());
    }

    // 生成短信评价数据 主程序本身已做了重复过滤，这里无需再操作
    @Override
    public Boolean addItfMessagehuifangentity(ItfMessagehuifangentity add,String orderType,int type){
        if (itfMessagehuifangentityService.save(add)){
            // 向发送短信表插入数据
            return addSmsRecord(add,orderType,type);
        }
        return Boolean.FALSE;
    }


    // 平台网点服务的大类信息
    private WebsitOrderSign websitCategory(String websitNo,List<WebsitOrderSign> wos, String categoryId,long tid,String type){
        String wd="";
        String wdh="";
        List<WebsitOrderSign> wosn = new ArrayList<>();

        // 对应多总包服务商 处理方式与一个总包服务商相同
        // 一个总包服务商多网点：从平台网点服务的类目取对应的网点信息 一般在这里就可以区分开
        for (WebsitOrderSign item:wos){
            WebsitServiceCategoryDetail wosinfo = getWebCategory(item.getBrandId(),item.getWebsitId(), categoryId,type);
            wd=wd+item.getWebsitId()+",";
            if (wosinfo !=null){
                wosn.add(item);
                wdh=wdh+item.getWebsitId()+",";
            }
        }
        log.info("网点一对多关系进行分类锁定：[{}][{}]",tid,wd.substring(0,wd.length()-1));

        if (wosn.size() ==0 ){
            log.info("分类锁定无对应的网点：{}",tid);
            // 这里返回一个至少可以正常下单
            return wosn.get(0);
            // return null;
        }
        if (wosn.size() ==1){
            log.info("分类锁定网点结果：[{}][{}]",tid,wosn.get(0).getWebsitId());
            return wosn.get(0);
        }

        log.info("分类锁定后网点一对多关系：[{}][{}]",tid,wdh.substring(0,wdh.length()-1));

        // 类别无法锁定时再进行位置过滤
        return getWebsitOrderSign(websitNo, wosn, tid);
    }

    @Nullable
    private WebsitOrderSign getWebsitOrderSign(String websitNo, List<WebsitOrderSign> wosn, long tid) {
        Map<String, List<WebsitOrderSign>> wosMap;
        String s = "";
        wosMap = wosn.stream().collect(Collectors.groupingBy(WebsitOrderSign::getWebsitId));
        // 依然有多个时按位置再次过滤 这里指网点的位置
        // 商户网点位置
        BrandWebsit bw = brandWebsitService.lambdaQuery()
                .eq(BrandWebsit::getBrandWebsitNumber, websitNo)
                .last("limit 1")
                .one();
        List<String> wdno = new ArrayList<>();
        // 有为空的按经纬度重新提取位置
        if (StringUtils.isEmpty(bw.getSfen()) ||
                StringUtils.isEmpty(bw.getCshi()) ||
                StringUtils.isEmpty(bw.getXian()) ||
                StringUtils.isEmpty(bw.getXzhen()) ||
                StringUtils.isEmpty(bw.getXzhen())){
            Geographicallocation jwd = getRegionByAddress(String.valueOf(bw.getJingdu()),String.valueOf(bw.getWeidu()));
            if (jwd ==null){
                log.info("重新获取商户网点位置失败：{}",tid);
                // throw new RemoteServiceException("重新获取商户网点位置失败！");
                // 这里返回一个至少可以正常下单
                return wosn.get(0);
            }
            bw.setSfen(jwd.getProvince());
            bw.setCshi(jwd.getCity());
            bw.setXian(jwd.getArea());
            bw.setXzhen(jwd.getStreet());
        }

        log.info("商户网点位置：[{}][{}-{}|{}|{}|{}]",tid,websitNo,bw.getSfen(),bw.getCshi(),bw.getXian(),bw.getXzhen());

        // 提取平台网点编号
        wosn.stream().forEach(wd->{
            wdno.add(wd.getWebsitId());
        });
        // 提取平台网点信息
        List<Websit> websits = websitService.lambdaQuery()
                .in(Websit::getWebsitId,wdno)
                .list();
        List<WebsitOrderSign> wosns = new ArrayList<>();
        // 网点的位置信息过滤 最低区级必有值
        for (Websit item:websits){
            // 全址比较
            if (item.getProvince().equals(bw.getSfen()) &&
                    item.getCity().equals(bw.getCshi()) &&
                    item.getArea().equals(bw.getXian()) &&
                    item.getStreet().equals(bw.getXzhen())){
                wosns.add(wosMap.get(item.getWebsitId()).get(0));
            }
            s=s+"["+item.getWebsitId()+"-"+
                    item.getProvince()+"|"+
                    item.getCity()+"|"+
                    item.getArea()+"|"+
                    item.getStreet()+"],";
        }
        log.info("平台服务商网点位置：[{}][{}]",tid,s.substring(0,s.length()-1));

        if (CollectionUtils.isEmpty(wosns)){
            log.info("网点位置销定无对应的网点：{}",tid);
            // return null;
            // 取其一至少可以下派网点
            return wosn.get(0);
        }

        // 全址对应只取其一即可
        log.info("网点位置销定结果：[{}][{}]",tid,wosn.get(0).getWebsitId());
        return wosn.get(0);
    }


    @Nullable
    private CustomerInformationWebsit getCustomerInformationWebsit(String websitNo, List<CustomerInformationWebsit> ciws) {
        Map<String, List<CustomerInformationWebsit>> wosMap;
        wosMap = ciws.stream().collect(Collectors.groupingBy(CustomerInformationWebsit::getWebsitId));
        // 依然有多个时按位置再次过滤 这里指网点的位置
        // 商户网点位置
        BrandWebsit bw = brandWebsitService.lambdaQuery()
                .eq(BrandWebsit::getBrandWebsitNumber, websitNo)
                .last("limit 1")
                .one();
        List<String> wdno = new ArrayList<>();
        // 有为空的按经纬度重新提取位置
        if (StringUtils.isNotEmpty(bw.getSfen()) ||
                StringUtils.isNotEmpty(bw.getCshi()) ||
                StringUtils.isNotEmpty(bw.getXian()) ||
                StringUtils.isNotEmpty(bw.getXzhen()) ||
                bw.getXzhen().length()<1){
            Geographicallocation jwd = getRegionByAddress(String.valueOf(bw.getJingdu()),String.valueOf(bw.getWeidu()));
            if (jwd ==null){
                return null;
            }
            bw.setSfen(jwd.getProvince());
            bw.setCshi(jwd.getCity());
            bw.setXian(jwd.getArea());
            bw.setXzhen(jwd.getStreet());
        }

        // 提取平台网点编号
        ciws.stream().forEach(wd->{
            wdno.add(wd.getWebsitId());
        });
        // 提取平台网点信息
        List<Websit> websits = websitService.lambdaQuery()
                .in(Websit::getWebsitId,wdno)
                .list();
        List<CustomerInformationWebsit> wosns = new ArrayList<>();
        // 网点的位置信息过滤 最低区级必有值
        for (Websit item:websits){
            // 全址比较
            if (item.getProvince().equals(bw.getSfen()) &&
                    item.getCity().equals(bw.getCshi()) &&
                    item.getArea().equals(bw.getXian()) &&
                    item.getStreet().equals(bw.getXzhen())){
                wosns.add(wosMap.get(item.getWebsitId()).get(0));
            }
        }
        if (CollectionUtils.isEmpty(wosns)){
            return null;
        }

        // 全址对应只取其一即可
        return ciws.get(0);
    }




    // 平台网点与其服务的大类 商户ID，商户网点，网点服务的大类
    private WebsitServiceCategoryDetail getWebCategory(String brandId,String websitId,String categoryId,String type){
        // 查看平台网点是否服务该类目 不存在即找到的网点不接该服务类型的工单
        return websitServiceCategoryDetailService.lambdaQuery()
                .eq(WebsitServiceCategoryDetail::getBrandId,brandId)
                .eq(WebsitServiceCategoryDetail::getWebsitId,websitId)
                .eq(WebsitServiceCategoryDetail::getType,type)
                .eq(WebsitServiceCategoryDetail::getMainId,categoryId)
                .last("limit 1")
                .one();
    }

    // 提取平台网点名称及服务热线
    private  void getNameAndHotline(WebsitFWS req){
        Websit websit = websitService.lambdaQuery()
                .eq(Websit::getWebsitId,req.getWebsitId())
                .last("limit 1")
                .one();

        if (websit != null){
            if (StringUtils.isNotEmpty(websit.getHotline())){
                req.setWdlxdh(websit.getHotline());
            } else if (StringUtils.isNotEmpty(websit.getOfficePhone())){
                req.setWdlxdh(websit.getOfficePhone());
            }
            if (StringUtils.isNotEmpty(websit.getWebsitName())){
                req.setWdmc(websit.getWebsitName());
            }
        }
    }

    private List<WebsitOrderSign> getWebsitOrderSign(String ppWebsitNo){
        List<WebsitOrderSign> wos = new ArrayList<>();
        wos = websitOrderSignService.lambdaQuery()
                .eq(WebsitOrderSign::getBrandWebsitId, ppWebsitNo)
                .list();
        return wos;
    }


}
