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


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zfire.jiasm.syncdata.base.BaseService;
import com.zfire.jiasm.syncdata.constant.DictTypeEnum;
import com.zfire.jiasm.syncdata.constant.ServiceCategoryEnum;
import com.zfire.jiasm.syncdata.gree.GreeLogic;
import com.zfire.jiasm.syncdata.helper.GreeResponseHelper;
import com.zfire.jiasm.syncdata.plus.entity.*;
import com.zfire.jiasm.syncdata.plus.service.*;
import com.zfire.jiasm.syncdata.request.SignSplb;
import com.zfire.jiasm.syncdata.request.ZJInfo;
import com.zfire.jiasm.syncdata.response.WangdianWxgVos;
import com.zfire.jiasm.syncdata.response.WxgQueryInfo;
import com.zfire.jiasm.syncdata.service.GLPPWXGQueryUpdateService;
import com.zfire.jiasm.syncdata.service.PublicService;
import com.zfire.jiasm.syncdata.utils.oss.OSSUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GLPPWXGQueryUpdateServiceImpl implements GLPPWXGQueryUpdateService {
    String wdqyapi = "/outapp/wxg/list";


    @Resource
    BaseService baseService;
    @Resource
    GreeLogic greeLogic;
    @Resource
    OSSUtil ossUtil;
    @Resource
    ItfTblWangdianWxgDownloadService itfTblWangdianWxgDownloadService;
    @Resource
    WorkerBrandAccountService workerBrandAccountService;
    @Resource
    WorkerCertService workerCertService;
    @Resource
    WorkerStreetService workerStreetService;
    @Resource
    WorkerServiceCategoryService workerServiceCategoryService;
    @Resource
    WorkerServiceCategoryDetailService workerServiceCategoryDetailService;
    @Resource
    SysDictRefService sysDictRefService;
    @Resource
    SysDictService sysDictService;
    @Resource
    PublicService publicService;




    @Override
    public void extractedQueryUpdate() throws Exception {
        WangdianWxgVos wvos = new WangdianWxgVos();
        List<WorkerBrandAccount> wbarecs = new ArrayList<>();
        Map<String,Object> req = new HashMap<>();
        List<WorkerServiceCategory> wscList = new ArrayList<>();
        List<WorkerServiceCategoryDetail> wscdList = new ArrayList<>();
        List<WorkerStreet> ws = new ArrayList<>();

        // 提取品牌信息
        Brand brand = baseService.getBrand();
        if (brand == null) {
            return;
        }

        // 字典表中查出ID 格力只有-家电售后
        SysDict sysDict =  sysDictService.lambdaQuery().
                eq(SysDict::getDictType, ServiceCategoryEnum.DICT_TYPE_SERVICE_CATEGORY.getCode())
                .eq(SysDict::getDictValue,ServiceCategoryEnum.DICT_TYPE_SERVICE_CATEGORY.getText())
                .last("limit 1")
                .one();
        if (sysDict == null) {
            return;
        }

        // 提取品牌商对应的大类信息
        List<SysDictRef> 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();
        Map<String, List<SysDictRef>> sysDictRefMap = sysDictRef.stream().
                collect(Collectors.groupingBy(SysDictRef::getRefDictCode));

        // 提取现有的师傅数据信息 师傅离职的情况不再处理
        List<ItfTblWangdianWxgDownload> wxgRecs =  itfTblWangdianWxgDownloadService.lambdaQuery()
                .select(ItfTblWangdianWxgDownload::getWxgno,
                        ItfTblWangdianWxgDownload::getWdno,
                        ItfTblWangdianWxgDownload::getSfzen)
                // .eq(ItfTblWangdianWxgDownload::getWxgno,"S21A03650250")// 测试用
                .like(ItfTblWangdianWxgDownload::getWdno,"S%").list();

        //本地提取商户师傅网点信息 一个师傅可多网点 格力最多3个网点
        wbarecs = workerBrandAccountService.lambdaQuery()
                .eq(WorkerBrandAccount::getBrandWorkerStatus,"ON")
                .eq(WorkerBrandAccount::getDel,0)
                .eq(WorkerBrandAccount::getGroupCompanyId, brand.getBrandId()).list();

        // 遍历格力总部的所有师傅信息
        for (ItfTblWangdianWxgDownload wxg :wxgRecs){
            // 本地提取商户师傅信息 按品牌，网点，师傅编号 不存在不处理
            WorkerBrandAccount workerBrandAccount = getWorkerBrandAccount(wbarecs, wxg);
            if (workerBrandAccount == null) {
                continue;
            }

            // 参数
            getParameter(wxg.getWdno(), wxg.getWxgno(), req);
            // 格力总部查询工程师信息
            GreeResponseHelper response = greeLogic.greePost(wdqyapi, JSONObject.toJSONString(req), publicService.getCompanyId(wxg.getWdno()));
            if (response.getStatus() == 200){
                WxgQueryInfo resultDatax = JSONObject.parseObject(response.getData().toString(), WxgQueryInfo.class);
                // 无数据不处理
                if (resultDatax.getWangdianWxgVos().size()<1){
                    continue;
                }
                wvos = resultDatax.getWangdianWxgVos().get(0);

                // 提取师傅的服务大类信息
                List<WorkerServiceCategoryDetail> wxgCategoryRecs = workerServiceCategoryDetailService.lambdaQuery()
                        .eq(WorkerServiceCategoryDetail::getWorkerId, wxg.getSfzen()).list();

                // 服务类型 INSTALL=安装 REPAIR=维修  DELIVERY=配送
                Map<String, List<WorkerServiceCategoryDetail>> wxgCategoryTypeRecs = wxgCategoryRecs.stream().
                        collect(Collectors.groupingBy(WorkerServiceCategoryDetail::getType));


                try {
                    // 证件同步  师傅证件照修改的不再做了，只做新增，王总的要求
                    /*for (ZJInfo zj:wvos.getZjInfoList()){
                        // 同步-新增或修改证件信息
                        // log.info("wxginfo {}",wxg);
                        workercertUpdataOrAdd(wvos, updateList, addList, workerBrandAccount, zj);
                    }*/

                    // 同步-师傅地理位置
                    // updateWorkerStreet(wvos,workerBrandAccount.getWorkerId(),brand.getBrandId(),ws);

                    // 同步-师傅服务的类目信息 无则插入
                    getServiceCategory(wvos, wscList, wscdList, sysDict, wxg, wxgCategoryTypeRecs, sysDictRefMap, workerBrandAccount);

                    // 新增或修改(证件,师傅地理位置,师傅服务的类目)
                    addOrUpdate(wscList, wscdList, ws);
                } catch (Exception ex) {
                    log.info("工程师信息同步失败:{}", ex);
                }
            }
        }
    }


    @Nullable
    private WorkerBrandAccount getWorkerBrandAccount(List<WorkerBrandAccount> wbarecs, ItfTblWangdianWxgDownload wxg) {
        WorkerBrandAccount workerBrandAccount = null;

        // 平台师傅信息未同步到格力总部时不处理
        for (WorkerBrandAccount wba: wbarecs){
            if (StringUtils.isEmpty(wba.getBrandWebsitId()) || StringUtils.isEmpty(wba.getBrandWorkerNumber()) ||
                    StringUtils.isEmpty(wxg.getWdno()) || StringUtils.isEmpty(wxg.getWxgno())){
                continue;
            }
            if (wba.getBrandWebsitId().equals(wxg.getWdno())
                    && wba.getBrandWorkerNumber().equals(wxg.getWxgno())){
                workerBrandAccount = wba;
                break;
            }
        }

        if (workerBrandAccount == null){
            return null;
        }

        // 师傅离职的情况不再处理
        if (wxg.getFlag() != null){
            if (!wxg.getFlag().trim().equals(DictTypeEnum.DICT_TYPE_FLAG_ON.getCode())
                    && workerBrandAccount.getBrandWorkerStatus().equals("OFF")){
                return null;
            }
        }
        return workerBrandAccount;
    }


    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(List<WorkerServiceCategory> wscList, List<WorkerServiceCategoryDetail> wscdList, List<WorkerStreet> ws) {

        // 同步-师傅地理位置
//        if (ws.size()>0){
//            workerStreetService.updateBatchById(ws);
//        }

        // 师傅服务类目新增
        if (wscList.size()>0){
            workerServiceCategoryService.saveBatch(wscList);
        }
        if (wscdList.size()>0){
            workerServiceCategoryDetailService.saveBatch(wscdList);
        }

        ws.clear();
        wscList.clear();
        wscdList.clear();
    }

    private void getServiceCategory(WangdianWxgVos wvos, List<WorkerServiceCategory> wscList, List<WorkerServiceCategoryDetail> wscdList,
                                    SysDict sysDict, ItfTblWangdianWxgDownload wxg,
                                    Map<String,List<WorkerServiceCategoryDetail>> wxgCategoryTypeRecs,
                                    Map<String, List<SysDictRef>> sysDictRefMap,WorkerBrandAccount workerBrandAccount) {
        List<String> complete = new ArrayList<>();
        // 先处理商用
        for (SignSplb syitem: wvos.getSySignSplbList()){
            // 扫描每个大类
            for (String s :syitem.getFwlbList()){
                // 师傅服务的大类中查看是否存在 不存在新增
                extracted(wscList, wscdList, complete, sysDict, wxg, wxgCategoryTypeRecs,
                        syitem, s,ServiceCategoryEnum.COMMERCIAL_TYPE.getCode(), sysDictRefMap, workerBrandAccount);
            }
        }
        complete.clear();

        // 处理家用
        for (SignSplb syitem: wvos.getJySignSplbList()){
            // 扫描每个大类
            for (String s :syitem.getFwlbList()){
                // 师傅服务的大类中查看是否存在 不存在新增
                extracted(wscList, wscdList, complete, sysDict, wxg, wxgCategoryTypeRecs,
                        syitem, s,ServiceCategoryEnum.HOME_TYPE.getCode(), sysDictRefMap,workerBrandAccount);
            }
        }
    }

    private void extracted(List<WorkerServiceCategory> wscList, List<WorkerServiceCategoryDetail> wscdList,
                           List<String> complete, SysDict sysDict, ItfTblWangdianWxgDownload wxg,
                           Map<String,List<WorkerServiceCategoryDetail>> wxgCategoryTypeRecs, SignSplb syitem,
                           String s, String type,Map<String, List<SysDictRef>> sysDictRefMap,WorkerBrandAccount workerBrandAccount) {
        if ( !complete.contains(s + syitem.getSpdl())){
            // 提取品牌商对应的大类信息
            SysDictRef sysDictRef = sysDictRefMap.get(String.valueOf(syitem.getSpdl())).get(0);

            if (s.equals(ServiceCategoryEnum.INSTALL_TYPE.getText())){
                getAddInfo(wscList, wscdList, sysDict, wxg, wxgCategoryTypeRecs,
                        sysDictRef,ServiceCategoryEnum.INSTALL_TYPE.getCode(),type,workerBrandAccount);
            } else if (s.equals(ServiceCategoryEnum.REPAIR_TYPE.getText())){
                getAddInfo(wscList, wscdList, sysDict, wxg, wxgCategoryTypeRecs,
                        sysDictRef,ServiceCategoryEnum.REPAIR_TYPE.getCode(),type,workerBrandAccount);
            } else if (s.equals(ServiceCategoryEnum.DELIVERY_TYPE.getText())){
                getAddInfo(wscList, wscdList, sysDict, wxg, wxgCategoryTypeRecs,
                        sysDictRef,ServiceCategoryEnum.DELIVERY_TYPE.getCode(),type,workerBrandAccount);
            }
            // 新增过的无需再次新增
            complete.add(s + syitem.getSpdl());
        }
    }


    private void getAddInfo(List<WorkerServiceCategory> wscList, List<WorkerServiceCategoryDetail> wscdList, SysDict sysDict,
                            ItfTblWangdianWxgDownload wxg, Map<String, List<WorkerServiceCategoryDetail>> wxgCategoryTypeRecs,
                            SysDictRef sysDictRef, String code, String type,WorkerBrandAccount workerBrandAccount) {
        Boolean include = Boolean.FALSE;
        // 看师傅是否已有（服务类型 INSTALL=安装 REPAIR=维修  DELIVERY=配送）对应的大类信息 如有不做任何处理
        if (wxgCategoryTypeRecs !=null && wxgCategoryTypeRecs.size()>0){
            if (wxgCategoryTypeRecs.containsKey(code)){
                for (WorkerServiceCategoryDetail category : wxgCategoryTypeRecs.get(code)){
                    if (category.getMainId().equals(sysDictRef.getDictCode())){
                        include = Boolean.TRUE;
                        break;
                    }
                }
            }
        }

        if (!include){
            // 新增
            // 看 worker_service_category 有无数据，无数据新增
            if (wxgCategoryTypeRecs ==null || wxgCategoryTypeRecs.size()<1 || !wxgCategoryTypeRecs.containsKey(code) ){
                //去重，判断是否存在
                List<WorkerServiceCategory> hasWorkerServiceCategory = wscList.stream().filter(v ->
                        org.apache.commons.lang3.StringUtils.equals(v.getWebsitWorkerId(), workerBrandAccount.getWebsitWorkerId())
                                && org.apache.commons.lang3.StringUtils.equals(v.getFlag(), type)
                                && org.apache.commons.lang3.StringUtils.equals(v.getType(), code)
                ).collect(Collectors.toList());

                WorkerServiceCategory wsc = null;
                if(CollectionUtils.isNotEmpty(hasWorkerServiceCategory)){
                    wsc = hasWorkerServiceCategory.get(0);
                }else {
                    wsc = new WorkerServiceCategory();
                    wsc.setId(IdWorker.getIdStr());
                    wsc.setWorkerId(workerBrandAccount.getWorkerId());
                    wsc.setWebsitId(workerBrandAccount.getWebsitId());
                    wsc.setWebsitWorkerId(workerBrandAccount.getWebsitWorkerId());
                    wsc.setServiceCategoryId(sysDict.getDictCode());
                    wsc.setServiceCategoryName(sysDict.getDictValue());
                    wsc.setFlag(type);
                    wsc.setType(code);
                    wsc.setCreateTime(new Date());
                    wscList.add(wsc);
                }

                // WorkerServiceCategoryDetail 新增
                WorkerServiceCategoryDetail wscd = new WorkerServiceCategoryDetail();
                wscd.setId(IdWorker.getIdStr());
                wscd.setWorkerServiceCategoryId(wsc.getId());
                wscd.setWorkerId(String.valueOf(wxg.getSfzen()));
                wscd.setServiceCategoryId(sysDict.getDictCode());
                wscd.setServiceCategoryName(sysDict.getDictValue());
                wscd.setFlag(type);
                wscd.setType(code);
                wscd.setMainId(sysDictRef.getDictCode());
                wscd.setMainName(sysDictRef.getDictValue());
                wscd.setCreateTime(new Date());

                wscdList.add(wscd);

            } else {
                // WorkerServiceCategoryDetail 新增
                WorkerServiceCategoryDetail wscd = new WorkerServiceCategoryDetail();
                wscd.setId(IdWorker.getIdStr());
                wscd.setWorkerServiceCategoryId(wxgCategoryTypeRecs.get(code).get(0).getWorkerServiceCategoryId());
                wscd.setWorkerId(workerBrandAccount.getWorkerId());
                wscd.setWebsitId(workerBrandAccount.getWebsitId());
                wscd.setWebsitWorkerId(workerBrandAccount.getWebsitWorkerId());
                wscd.setServiceCategoryId(sysDict.getDictCode());
                wscd.setServiceCategoryName(sysDict.getDictValue());
                wscd.setFlag(type);
                wscd.setType(code);
                wscd.setMainId(sysDictRef.getDictCode());
                wscd.setMainName(sysDictRef.getDictValue());
                wscd.setCreateTime(new Date());
                wscdList.add(wscd);
            }
        }
    }

    private void workercertUpdataOrAdd(WangdianWxgVos wvos, List<WorkerCert> updateList,
                                       List<WorkerCert> addList, WorkerBrandAccount workerBrandAccount,
                                       ZJInfo zj) throws Exception {
        // 师傅证件信息 按证件名提取
        WorkerCert old = workerCertService.lambdaQuery()
                .eq(WorkerCert::getWorkerId, workerBrandAccount.getWorkerId())
                .eq(WorkerCert::getCertName, zj.getZjmc())
                .last("limit 1")
                .one();

        if (old !=null){
            // 修改
            getUpdate(updateList, zj, old);
        } else {
            // 新增
            getAdd(addList, workerBrandAccount.getWorkerId(), zj.getZjmc(), wvos.getXingb(), zj);
        }
        // 上传图片
        /*if (updateList.size()>0){
            updateUpload(updateList);
        }
        if (addList.size()>0){
            addUload(addList);
        }*/
    }

    private void getAdd(List<WorkerCert> addList, String workerId, String zjmc,String xingb,  ZJInfo zj) throws Exception {
        WorkerCert add = new WorkerCert();
        add.setId(publicService.getUUID());
        add.setWorkerId(workerId);
        add.setCertName(zjmc);

        if (zj.getZjlj().contains(",")){
            List<String> result = Arrays.asList(zj.getZjlj().split(","));
            add.setOutFileUrl(result.get(0));
            add.setOutFileUrl2(result.get(1));
            // 上传图片
            String id = putCert(result.get(0));
            add.setFileUrl(id);
            String id2 = putCert(result.get(1));
            add.setFileUrl2(id2);
            new File(id).delete();
            new File(id2).delete();
        } else {
            add.setOutFileUrl(zj.getZjlj());
            String id = putCert(zj.getZjlj());
            add.setFileUrl(id);
            new File(id).delete();
        }
        if (zj.getZjbh().contains("/")){
            List<String> result = Arrays.asList(zj.getZjbh().split("/"));
            add.setCertNo(result.get(1));
        } else {
            add.setCertNo(zj.getZjbh());
        }
        if (StringUtils.isNotEmpty(zj.getZjyxq())){
            add.setExpireTime(baseService.utcToDateStr(zj.getZjyxq()));
        }
        if (StringUtils.isNotEmpty(zj.getZjfssj())){
            add.setReviewTime(baseService.utcToDateStr(zj.getZjfssj()));
        }

        // add.setExamineStatus("OK");
        add.setSex(xingb);
        add.setOutSyncStatus(1);
        add.setOutSyncTimes(0);
        add.setOutSyncTime(new Date());

        addList.add(add);
    }

    @NotNull
    private String putCert(String image) throws Exception {
        String id = publicService.path(image);
        File nFile = new File(id);

        baseService.saveToFile(greeLogic.greeFileUrl(image), nFile);
        String file = id;
        ossUtil.uploadFile(id, new File(file));
        nFile.delete();

        return id;
    }


    private void getUpdate(List<WorkerCert> updateList,ZJInfo zj,WorkerCert old) throws Exception {
        Boolean flag = Boolean.FALSE;
        WorkerCert up = new WorkerCert();
        if (zj.getZjlj().contains(",")){
            List<String> result = Arrays.asList(zj.getZjlj().split(","));
            if ((!old.getOutFileUrl().equals(result.get(0)) && !old.getOutFileUrl2().equals(result.get(0)))
                    || (!old.getOutFileUrl().equals(result.get(1)) && !old.getOutFileUrl2().equals(result.get(1)))){
                up.setId(old.getId());
                up.setOutFileUrl(result.get(0));
                up.setOutFileUrl2(result.get(1));

                // 上传图片
                String id = putCert(result.get(0));
                up.setFileUrl(id);
                String id2 = putCert(result.get(1));
                up.setFileUrl2(id2);

                new File(id).delete();
                new File(id2).delete();

                flag = Boolean.TRUE;
            }
        } else {
            if (!old.getOutFileUrl().equals(zj.getZjlj()) && !old.getOutFileUrl2().equals(zj.getZjlj())) {
                up.setId(old.getId());
                up.setOutFileUrl(zj.getZjlj());
                // 上传图片
                String id = putCert(zj.getZjlj());
                up.setFileUrl(id);

                new File(id).delete();
                flag = Boolean.TRUE;
            }
        }
        if (flag){
            up.setOutSyncTime(new Date());
            updateList.add(up);
        }
    }

    private void getParameter(String wdno, String wxgno, Map<String, Object> req) {
        req.put("wdno", wdno);
        req.put("wxgno", wxgno);
        req.put("page", 1);
        req.put("size", 20);
        req.put("xsgsshstat", 2);
    }

}
