package com.yeejoin.amos.boot.module.jxiop.biz.service.impl;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yeejoin.amos.boot.biz.common.excel.ExcelUtil;
import com.yeejoin.amos.boot.module.common.api.dto.*;
import com.yeejoin.amos.boot.module.jxiop.api.dto.EXPersonUser;
import com.yeejoin.amos.boot.module.jxiop.api.dto.ExStationBasicDto;
import com.yeejoin.amos.boot.module.jxiop.api.dto.ProduceMsg;
import com.yeejoin.amos.boot.module.jxiop.api.entity.*;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.PersonBasicMapper;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.StationBasicMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.activemq.QuerueProduce;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Case;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.utils.Bean;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@Service
public class ExcelServiceImpl {

    @Autowired
    ExDataSourcesImpl dataSourcesImpl;

    @Autowired
    StationBasicServiceImpl stationBasicServiceImpl;
    @Autowired
    PersonBasicServiceImpl personBasicServiceImpl;


    @Autowired
    PersonBasicMapper personBasicMapper;
    @Autowired
    StationBasicMapper stationBasicMapper;
    //人员资质信息service
    @Autowired
    PersonCertificateServiceImpl personCertificateService;
    //人员教育信息
    @Autowired
    PersonSkillEducationServiceImpl personSkillEducationService;
    @Autowired
    PersonAccountServiceImpl personAccountServiceImpl;

    @Autowired
    QuerueProduce querueProduce;

    // 邮箱校验正则
    static final String EMAIL = "^([a-zA-Z\\d][\\w-]{2,})@(\\w{2,})\\.([a-z]{2,})(\\.[a-z]{2,})?$";
    /**
     * 电话校验正则
     */
    static final String PHONE = "^1((3|4|5|6|7|8|9){1}\\d{1}|70)\\d{8}$";

    private String EXPORT="EXPORT";

    public void templateExport(HttpServletResponse response, ExcelDto excelDto, Map par) throws ClassNotFoundException {
        String url = excelDto.getClassUrl();
        Class<?> clz = Class.forName(url);

        switch (excelDto.getType()) {

            case "RYXX":
                //List<EXPersonUser> data=this.getEXPersonUser( par);
                List<EXPersonUser> data = this.getEXPersonUserAll(par);
                ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), data,
                        clz, dataSourcesImpl, true);
                break;
            default:
                ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), null, clz, dataSourcesImpl,
                        true);
                break;
        }
    }

    public void commonExport(HttpServletResponse response, ExcelDto excelDto, Map par) {

        switch (excelDto.getType()) {

            case "CZXX":
                List<ExStationBasicDto> data = this.getExStationBasicDto(par);
                ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), data,
                        ExStationBasicDto.class, dataSourcesImpl, false);
                break;
            case "RYXX":
                List<EXPersonUser> datad = this.getEXPersonUserAll(par);
                ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), datad,
                        EXPersonUser.class, dataSourcesImpl, false);
                break;
            default:
                break;
        }
    }

    @Transactional
    public void commonUpload(MultipartFile multipartFile, ExcelDto excelDto) throws Exception {
        switch (excelDto.getType()) {
            case "CZXX":
                this.addExStationBasicDto(multipartFile);
                break;
            case "RYXX":
                this.updateEXPersonUser(multipartFile);
                break;
        }
        return;
    }


    //场站信息导出
    public List<ExStationBasicDto> getExStationBasicDto(Map<String, Object> map) {
        List<ExStationBasicDto> data = null;
        if (!map.isEmpty()) {
            String[] ids = null;
            if (map.containsKey("ids") && map.get("ids") != null && !"".equals(map.get("ids").toString())) {
                ids = map.get("ids").toString().split(",");
            }


            data = stationBasicMapper.getExStationBasicDto(
                    map.containsKey("stationMasterName") ? map.get("stationMasterName").toString() : null,
                    map.containsKey("stationName") ? map.get("stationName").toString() : null,
                    map.containsKey("stationType") ? map.get("stationType").toString() : null,
                    map.containsKey("orgCode") ? map.get("orgCode").toString() : null,
                    ids
            );

        }
        return data;
    }

    //场站导入
    private void addExStationBasicDto(MultipartFile multipartFile) throws Exception {
        List<ExStationBasicDto> excelDtoList = ExcelUtil.readFirstSheetExcel(multipartFile, ExStationBasicDto.class, 1);
        List<StationBasic> excelEntityList = new ArrayList<>();

        //数据验证
        for (int i = 0; i < excelDtoList.size(); i++) {
            ExStationBasicDto exStationBasicDto = excelDtoList.get(i);
            this.yanzheng(exStationBasicDto.getStationName(), "场站名称", i);
            this.yanzheng(exStationBasicDto.getStationCode(), "场站编号", i);
            this.yanzheng(exStationBasicDto.getStationFlag(), "项目状态", i);
            this.yanzheng(exStationBasicDto.getStationType(), "场站类型", i);
            this.yanzheng(exStationBasicDto.getStationMasterName(), "站长", i);
            this.yanzheng(exStationBasicDto.getMobilePhone(), "手机号码", i);
            this.yanzheng(exStationBasicDto.getEmail(), "邮箱", i);
            this.yanzheng(exStationBasicDto.getDevopsTime(), "运维时间", i);
            this.yanzheng(exStationBasicDto.getOwnerUnit(), "运维单位", i);
            this.yanzheng(exStationBasicDto.getAddress(), "场站地址", i);
            this.yanzheng(exStationBasicDto.getArea(), "所属片区", i);
            this.yanzheng(exStationBasicDto.getBriefIntroduction(), "场站简介", i);
        }
        excelDtoList.forEach(item -> {
            StationBasic fireChemical = new StationBasic();
            fireChemical = Bean.toPo(item, fireChemical);
            if (fireChemical.getArea() != null) {
                String[] type = fireChemical.getArea().split("@");
                fireChemical.setAreaName(type[0]);
                fireChemical.setArea(type[1]);
                CompanyModel companyModel = personBasicServiceImpl.getCompanyModel(Long.parseLong(type[1]));
                fireChemical.setAreaCode(companyModel.getCompanyCode());
            }
            if (fireChemical.getStationType() != null) {
                String[] type = fireChemical.getStationType().split("@");
                fireChemical.setStationTypeName(type[0]);
                fireChemical.setStationType(type[1]);
            }


            //平台增加场站
            CompanyModel companyModeldata = new CompanyModel();
            companyModeldata.setCompanyName(fireChemical.getStationName());
            companyModeldata.setCompanyType("company");
            companyModeldata.setLevel("station");
            companyModeldata.setParentId(Long.valueOf(fireChemical.getArea()));
            companyModeldata.setCompanyCode(fireChemical.getStationCode());
            companyModeldata = this.addCompanyModel(companyModeldata);

            fireChemical.setProjectOrgCode(companyModeldata.getOrgCode());
            fireChemical.setPlatformStationId(companyModeldata.getSequenceNbr().toString());
            excelEntityList.add(fireChemical);
        });

        stationBasicServiceImpl.saveBatch(excelEntityList);
    }

    //获取人员数据

    public List<EXPersonUser> getEXPersonUser(Map map) {
        List<EXPersonUser> listdata = personBasicMapper.getEXPersonUser(
                map.containsKey("name") ? map.get("name").toString() : null,
                map.containsKey("accountName") ? map.get("accountName").toString() : null,
                map.containsKey("projectName") ? map.get("projectName").toString() : null,
                map.containsKey("orgCode") ? map.get("orgCode").toString() : null);
        return listdata;
    }


    public void yanzheng(Object obj, String name, int i) {
        //验证数据库重复
        if (obj == null) {
            throw new InnerInvokException("第" + (i + 2) + "行，" + name + "数据不能空", "403", "第" + (i + 2) + "行，" + name + "数据不能空", 403);
        }
        if (obj != null && name.equals("手机号码") && String.valueOf(obj).matches(PHONE)) {
            throw new InnerInvokException("第" + (i + 2) + "行，手机号码填写错误", "403", "第" + (i + 2) + "行，" + name + "手机号码填写错误", 403);
        }
        if (obj != null && name.equals("邮箱") && String.valueOf(obj).matches(EMAIL)) {
            throw new InnerInvokException("第" + (i + 2) + "行，邮箱填写错误", "403", "第" + (i + 2) + "行，" + name + "邮箱填写错误", 403);
        }
    }


    //人员导出

    public List<EXPersonUser> getEXPersonUserAll(Map map) {
        String[] ids = null;
        if (map.containsKey("ids") && map.get("ids") != null && !"".equals(map.get("ids").toString())) {
            ids = map.get("ids").toString().split(",");
        }
        List<EXPersonUser> listdata = personBasicMapper.getEXPersonUserAll(
                map.containsKey("name") ? map.get("name").toString() : null,
                map.containsKey("accountName") ? map.get("accountName").toString() : null,
                map.containsKey("projectName") ? map.get("projectName").toString() : null,
                map.containsKey("orgCode") ? map.get("orgCode").toString() : null,
                ids);
        return listdata;
    }

    private CompanyModel addCompanyModel(CompanyModel companyModel) {
        FeignClientResult<CompanyModel> Model = Privilege.companyClient.create(companyModel);
        CompanyModel user = new CompanyModel();

        if (!ObjectUtils.isEmpty(Model)) {
            if (Model.getStatus() == 200) {
                user = Model.getResult();
            } else {
                throw new RuntimeException(Model.getMessage());
            }
        }
        return user;
    }

    //人员导入更新
    private void updateEXPersonUser(MultipartFile multipartFile) throws Exception {
        List<EXPersonUser> excelDtoList = ExcelUtil.readFirstSheetExcel(multipartFile, EXPersonUser.class, 1);
        this.updateEXPersonUserda(excelDtoList);

    }


    private List<String> getDataDictionary(String type) {
        List<String> collect = new ArrayList<>();
        FeignClientResult<List<DictionarieValueModel>> de = Systemctl.dictionarieClient.dictValues(type);
        List<DictionarieValueModel> listco = new ArrayList<>();
        if (!ObjectUtils.isEmpty(de)) {
            if (de.getStatus() == 200) {
                listco = de.getResult();
                for (DictionarieValueModel dictionarieValueModel : listco) {
                    collect.add(dictionarieValueModel.getDictDataValue());
                }
            } else {
                throw new RuntimeException(de.getMessage());
            }
        }
        return collect;
    }

    public void getdata(List<String> list, String name, int i) {

        if (name != null && !list.contains(name)) {
            throw new InnerInvokException("第" + (i + 2) + "行，证件类型和证件名称不匹配", "403", "第" + (i + 2) + "行，证件类型和证件名称不匹配", 403);
        }

    }


    @Transactional
    public void updateEXPersonUserda(List<EXPersonUser> excelDtoList) {
        List<String> listdata = new ArrayList<>();
        List<PersonBasic> listPersonBasic = new ArrayList<>();
        List<PersonSkillEducation> listPersonSkillEducation = new ArrayList<>();
        List<PersonCertificate> listPersonCertificate = new ArrayList<>();
        QueryWrapper<PersonAccount> wrapper = new QueryWrapper();
        //效验证件类型获取四种字典
        List<String> list1 = getDataDictionary("职业技能鉴定证书");
        List<String> list2 = getDataDictionary("专业技术资格证书");
        List<String> list3 = getDataDictionary("岗位资质鉴定证书");
        List<String> list4 = getDataDictionary("技能鉴定工种");
        //数据验证
        for (int i = 0; i < excelDtoList.size(); i++) {
            if (excelDtoList.get(i).getAccountName() != null) {
                wrapper.eq("account_name", excelDtoList.get(i).getAccountName());
                PersonAccount personAccount = personAccountServiceImpl.getOne(wrapper);
                if (personAccount == null) {
                    throw new InnerInvokException("第" + (i + 2) + "行，平台账号名名称错误请检查", "403", "第" + (i + 2) + "行，平台账号名名称错误请检查", 403);
                }
                //姓名
                if (excelDtoList.get(i).getName() != null && (!excelDtoList.get(i).getName().equals(personAccount.getName()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行，姓名不允许导入时修改", "403", "第" + (i + 2) + "行，姓名不允许导入时修改", 403);
                }
                //工号
                if (excelDtoList.get(i).getJobNumber() != null && (!excelDtoList.get(i).getJobNumber().equals(personAccount.getJobNumber()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行，工号不允许导入时修改", "403", "第" + (i + 2) + "行，工号不允许导入时修改", 403);
                }
                //所属场站
                if (excelDtoList.get(i).getProjectName() != null && (!excelDtoList.get(i).getProjectName().equals(personAccount.getProjectName()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行,所属场站不允许导入时修改", "403", "第" + (i + 2) + "行，行所属场站不允许导入时修改", 403);
                }
                //证件类型
                if (excelDtoList.get(i).getIdType() != null && (!excelDtoList.get(i).getIdType().equals(personAccount.getIdType()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行，证件类型不允许导入时修改", "403", "第" + (i + 2) + "行，证件类型不允许导入时修改", 403);
                }
                //证件编号
                if (excelDtoList.get(i).getIdNumber() != null && (!excelDtoList.get(i).getIdNumber().equals(personAccount.getIdNumber()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行，证件编号不允许导入时修改", "403", "第" + (i + 2) + "行，证件编号不允许导入时修改", 403);
                }
                PersonBasic personBasic = personBasicMapper.selectById(personAccount.getPersonId());
                //电话
                if (excelDtoList.get(i).getPhoneNum() != null && (!excelDtoList.get(i).getPhoneNum().equals(personBasic.getPhone()))) {
                    throw new InnerInvokException("第" + (i + 2) + "行，电话不允许导入时修改", "403", "第" + (i + 2) + "行，电话不允许导入时修改", 403);
                }
            }


            //身高和体重 ，字段验证
            if (excelDtoList.get(i).getWeight() != null && (0 >= excelDtoList.get(i).getWeight() || excelDtoList.get(i).getWeight() > 200)) {
                throw new InnerInvokException("第" + (i + 2) + "行，体重必须大于0小于等于200", "403", "第" + (i + 2) + "行，体重必须大于0小于等于200", 403);
            }
            if (excelDtoList.get(i).getHeight() != null && (0 >= excelDtoList.get(i).getHeight() || excelDtoList.get(i).getHeight() > 200)) {
                throw new InnerInvokException("第" + (i + 2) + "行，身高必须大于0小于等于200", "403", "第" + (i + 2) + "行，身高必须大于0小于等于200", 403);
            }

            //效验类型
            if (excelDtoList.get(i).getDocumentType() != null) {
                switch (excelDtoList.get(i).getDocumentType()) {
                    case "职业技能鉴定证书":
                        getdata(list1, excelDtoList.get(i).getCertificateName(), i);
                        break;
                    case "专业技术资格证书":
                        getdata(list2, excelDtoList.get(i).getCertificateName(), i);
                        break;
                    case "岗位资质鉴定证书":
                        getdata(list3, excelDtoList.get(i).getCertificateName(), i);
                        break;
                    case "技能鉴定工种":
                        getdata(list4, excelDtoList.get(i).getCertificateName(), i);
                        break;
                    default:
                        break;
                }

            }

        }


        for (EXPersonUser exPersonUser : excelDtoList) {
            //根据平台账号获取用户id
            wrapper.eq("account_name", exPersonUser.getAccountName());
            PersonAccount personAccount = personAccountServiceImpl.getOne(wrapper);
            listdata.add(personAccount.getPuserId());
            //获取基本信息
            PersonBasic personBasic = personBasicMapper.selectById(personAccount.getPersonId());

            BeanUtils.copyProperties(exPersonUser, personBasic);
            listPersonBasic.add(personBasic);
            //人员技能
            QueryWrapper<PersonSkillEducation> wrapper1 = new QueryWrapper();
            wrapper1.eq("person_id", personAccount.getPersonId());
            PersonSkillEducation personSkillEducation = personSkillEducationService.getOne(wrapper1);
            BeanUtils.copyProperties(exPersonUser, personSkillEducation);
            listPersonSkillEducation.add(personSkillEducation);
            //人员资质
            QueryWrapper<PersonCertificate> wrapper2 = new QueryWrapper();
            wrapper2.eq("person_id", personAccount.getPersonId());
            PersonCertificate personCertificate = personCertificateService.getOne(wrapper2);
            BeanUtils.copyProperties(exPersonUser, personCertificate);
            listPersonCertificate.add(personCertificate);
        }
        personBasicServiceImpl.saveOrUpdateBatch(listPersonBasic);
        personSkillEducationService.saveOrUpdateBatch(listPersonSkillEducation);
        personCertificateService.saveOrUpdateBatch(listPersonCertificate);

        Map<String, Object> data=new HashMap<>();
        data.put("USER_ID",listdata);
        ProduceMsg produceMsg=  new ProduceMsg(data, EXPORT,null);
        querueProduce.produceMsg(JSON.toJSONString(produceMsg));


    }

}
