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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mysql.cj.xdevapi.JsonArray;
import com.mysql.cj.xdevapi.Result;
import com.stoyanr.evictor.queue.NavigableMapEvictionQueue;
import com.yeejoin.amos.boot.module.tdc.api.dto.CheckResultDto;
import com.yeejoin.amos.boot.module.tdc.api.dto.DimensionTableDto;
import com.yeejoin.amos.boot.module.tdc.api.dto.ModelTreeDto;
import com.yeejoin.amos.boot.module.tdc.api.entity.*;
import com.yeejoin.amos.boot.module.tdc.api.enums.WordPowerTypeEum;
import com.yeejoin.amos.boot.module.tdc.api.feign.IdxFeignService;
import com.yeejoin.amos.boot.module.tdc.api.mapper.CheckModelMapper;
import com.yeejoin.amos.boot.module.tdc.api.mapper.CheckReportMapper;
import com.yeejoin.amos.boot.module.tdc.api.mapper.CheckResultMapper;
import com.yeejoin.amos.boot.module.tdc.api.mapper.ModelItemMapper;
import com.yeejoin.amos.boot.module.tdc.api.service.CheckReportService;
import com.yeejoin.amos.boot.module.tdc.api.service.CheckResultService;
import com.yeejoin.amos.boot.module.tdc.api.utils.WordPowerUtils;
import com.yeejoin.amos.boot.module.tdc.api.vo.SubjectTreeVo;
import com.yeejoin.amos.boot.module.tdc.api.vo.TableColumnsVo;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import liquibase.pro.packaged.M;
import org.codehaus.jettison.json.JSONString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CheckResultImpl extends ServiceImpl<CheckResultMapper, CheckResult> implements CheckResultService {

    @Autowired
    CheckResultMapper checkResultMapper;

    @Autowired
    IdxFeignService idxFeignService;

    @Autowired
    CheckReportService checkReportService;

    @Autowired
    CheckReportMapper checkReportMappere;

    @Autowired
    CheckModelMapper checkModelMapper;

    @Autowired
    ModelItemMapper modelItemMapper;

    @Override
    public IPage<CheckResultDto> selectResult(int current,int size,String code) {
        Page page = new Page(current,size);
        return checkResultMapper.selectResult(page,code);
    }

    @Override
    public List<CheckResult> selectCheckResult(String batchNo) {
        LambdaQueryWrapper<CheckResult> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckResult::getCheckItemResult, "1")
                .isNotNull(CheckResult::getBatchNo)
                .eq(CheckResult::getBatchNo,batchNo);
        return baseMapper.selectList(wrapper);
    }

     //统计不合格项和校验项接口
    @Override
    public Map<String, Object> selectTotal(String batchNo) {
        return checkResultMapper.selectTotal(batchNo);
    }



    @Override
    public List<CheckResultDto> selectStatistion(String batchNo, String amosOrgCode) {
        return checkResultMapper.selectStatistion(batchNo, amosOrgCode);
    }

    @Override
    public List<CheckResultDto> selectDetails(String batchNo, Integer modelId) {
        return checkResultMapper.selectDetails(batchNo, modelId);
    }


    @Override
    public List<ModelTreeDto> getAllModelDataTree(String amosOrgCode) {
        List<ModelTreeDto> modelTreeDtoList = new ArrayList<>();
        LambdaQueryWrapper<CheckModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckModel::getAmosOrgCode, amosOrgCode);
        List<CheckModel> checkModels = checkModelMapper.selectList(wrapper);

        checkModels.forEach(checkModel -> {
            ModelTreeDto modelTreeDto = selectDataTree(String.valueOf(checkModel.getSequenceNbr()));
            modelTreeDtoList.add(modelTreeDto);
        });

//        ResponseModel<List<JSONObject>> listResponseModel = idxFeignService.subjectTree("d2528788-b8d5-4170-ae62-edf153fddc59");
//        List<JSONObject> result = listResponseModel.getResult();
//        result.forEach(obj ->{
//            JSONArray tables = (obj).getJSONArray("tables");
//            tables.forEach(table -> {
//                ModelTreeDto modelTreeDto = new ModelTreeDto();
//                SubjectTreeVo subjectTreeVo = JSON.parseObject(JSON.toJSONString(table), SubjectTreeVo.class);
//                select(modelTreeDto, subjectTreeVo);
//                modelTreeDtoList.add(modelTreeDto);
//            });
//        });
        return modelTreeDtoList;
    }



    private ModelTreeDto selectDataTree(String modelId) {
        ModelTreeDto modelTreeDto = new ModelTreeDto();
        LambdaQueryWrapper<CheckModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckModel::getSequenceNbr, modelId);
        CheckModel checkModel = checkModelMapper.selectOne(wrapper);
        if (ObjectUtils.isEmpty(checkModel)) {
            return modelTreeDto;
        }
        ResponseModel<JSONObject> listResponseModel = idxFeignService.queryByTableId(checkModel.getTableId());
        JSONObject result = listResponseModel.getResult();
        SubjectTreeVo subjectTreeVo = JSON.parseObject(JSON.toJSONString(result), SubjectTreeVo.class);
        modelTreeDto.setId(checkModel.getTableId());
        modelTreeDto.setName(checkModel.getModelName());
        modelTreeDto.setTableName(checkModel.getIdxTableName());
        modelTreeDto.setModelId(String.valueOf(checkModel.getSequenceNbr()));
        modelTreeDto.setAmosOrgName(checkModel.getAmosOrgName());
        List<TableColumnsVo> columns = subjectTreeVo.getTableCols();
        Map tableMap = checkResultMapper.getTables(subjectTreeVo.getTableName(), checkModel.getAmosOrgCode());
        List<Map<String, Object>> list = new ArrayList<>();
        //TODO 不校验项  后期提出去，或数据库增加配置
        String noItem = "org_code,biz_org_code,biz_org_name,station_name,station_code,inspector,check_item_value,factory_classify,fire_spacing_class,auditClas,distanceType,firewallClass";
        String[] split = noItem.split(",");
        columns.forEach(tableColumnsVo -> {
            List<String> collect = Arrays.stream(split).filter(item -> item.equals(tableColumnsVo.getColumnName())).collect(Collectors.toList());
            if (collect.size() == 0) {
                Map<String, Object> map = new HashMap<>(3);
                map.put("name", tableColumnsVo.getName());
                map.put("id", tableColumnsVo.getId());
                map.put("data", tableMap.get(tableColumnsVo.getColumnName()));
                list.add(map);
            }
        });
        modelTreeDto.setChildren(list);
        return modelTreeDto;
    }


    @Override
    public List<ModelTreeDto> getModelDataTree(String modelId) {
        List<ModelTreeDto> modelTreeDtoList = new ArrayList<>();
        ModelTreeDto modelTreeDto = selectDataTree(modelId);
        modelTreeDtoList.add(modelTreeDto);
        return modelTreeDtoList;
    }

    @Override
    public Integer selectItemCount(String batchNo) {
        LambdaQueryWrapper<CheckResult> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckResult::getBatchNo, batchNo);
        return this.baseMapper.selectCount(wrapper);
    }

    @Override
    public Integer selectItemNo(String batchNo, Long modelId) {
        LambdaQueryWrapper<CheckResult> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CheckResult::getBatchNo, batchNo);
        wrapper.eq(CheckResult::getModelId, modelId);
        wrapper.eq(CheckResult::getCheckItemResult, 1);
        return this.baseMapper.selectCount(wrapper);
    }

    @Override
    public List<DimensionTableDto> getDimensionTable(String id) {
        ResponseModel<JSONObject> dimensionTable = idxFeignService.getDimensionTable(id);
        JSONObject result = dimensionTable.getResult();
        DimensionTableDto subjectTreeVo = JSON.parseObject(JSON.toJSONString(result), DimensionTableDto.class);
        return subjectTreeVo.getChildren();
    }


    /**
     * 获取报告数据
     * @param amosOrgCode
     * @return
     */
    private Map<String,Object> getData(String amosOrgCode, String batchNo) {
        Map<String,Object> map = new HashMap<>();

        //获取统计表信息
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        List<CheckResultDto> selectBatch = checkResultMapper.getOne(amosOrgCode);
//        for(CheckResultDto checkResultDto1 : selectBatch){
            List<CheckResultDto> systemList = selectStatistion(batchNo, amosOrgCode);

            for (CheckResultDto system : systemList) {
                HashMap<String, Object> data = new HashMap<>();

                map.put("station",system.getAmosOrgName());
                data.put("modelName",system.getModelName());
                System.out.println(system.getModelName()+"----------------------------------------------------------------");
                data.put("allTotal",system.getAllTotal());
                data.put("failTotal",system.getFailTotal());
                list.add(data);

                map.put("list",list);
            }

            // 获取时间
            String date = new SimpleDateFormat("yyyy-MM-dd ").format(Calendar.getInstance().getTime());
            map.put("time", date);

            //获取校验明细信息
            ArrayList<Map<String,Object>> list2 = new ArrayList<>();
            systemList.forEach(checkResultDto -> {
                List<CheckResultDto> systemList2 = selectDetails( checkResultDto.getBatchNo(), checkResultDto.getModelId());

                HashMap<String,Object> object = new HashMap<>();
                ArrayList<Map<String,Object>> maps = new ArrayList<>();
                object.put("modelName", checkResultDto.getModelName());
                for(CheckResultDto system2: systemList2) {
                    //HashMap<String,Object> datas = new HashMap<>();


                    //for(CheckResultDto system3: systemList2){
                    HashMap<String, Object> item = new HashMap<>();
                    item.put("checkitemlabel", system2.getCheckItemLabel());
                    item.put("checkitemvalue", system2.getCheckItemValue());
                    item.put("isright", system2.getIsRight());
                    item.put("checkexplain", system2.getCheckExplain());
                    maps.add(item);
                    //}
                }
                object.put("itemList",maps);
                list2.add(object);
                map.put("list2",list2);

            });
//        }
        return map;
    }

    /**
     * 调用方法获取报告的返回地址
     * @param amosOrgCode
     * @return
     */
    public String getUrl(String amosOrgCode, String batchNo) {
        Map<String, Object> dataMap = getData(amosOrgCode, batchNo);
        WordPowerUtils instance = WordPowerUtils.getInstance();
        String pdfUrlString = "";
        File filepdf = null;
        try {
            filepdf = instance.getWordFileItem(dataMap, null, WordPowerTypeEum.select.getTemplateFile());
            filepdf.getAbsolutePath();
            MultipartFile multipartFile = new PowerReportFile("file", "file.pdf", "application/pdf", file2byte(filepdf));
            FeignClientResult<Map<String, String>> result = Systemctl.fileStorageClient.updateCommonFile(multipartFile);
            if (result != null) {
                Iterator<String> it = result.getResult().keySet().iterator();
                while (it.hasNext()) {
                    pdfUrlString = it.next();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (filepdf != null) {
                filepdf.delete();
            }
        }
        return pdfUrlString;
    }

    /**
     * 通过amosOrgCode查询name，放入数据库
     * @param amosOrgCode
     * @return
     */
    public String searchName(String amosOrgCode){
        String name = null;
        List<CheckResultDto> result = checkResultMapper.getOne(amosOrgCode);
        for(CheckResultDto results : result){
           name =  results.getAmosOrgName();
        }
        return name;
    }


    /**
     * 拿到getUrl的url存储到数据库
     * @param amosOrgCode
     * @return
     */
    @Override
    public String saveSql(String amosOrgCode,String userName, String batchNo){
        String url = getUrl(amosOrgCode, batchNo);
        CheckReport checkReport = new CheckReport();
        checkReport.setReportUrl(url);
        checkReport.setCreateDate(new Date());
        checkReport.setAmosOrgCode(amosOrgCode);
        String name = searchName(amosOrgCode);
        checkReport.setAmosOrgName(name);
        checkReport.setName(name.concat(""+"三维校验"));
        checkReport.setCheckPeopleName(userName);
        checkReportService.save(checkReport);
        return null;
    }



    /**
     * 转换成流的形式读取
     * @param file
     * @return
     */
    private static byte[] file2byte(File file) {
        try {
            FileInputStream in = new FileInputStream(file);
            byte[] data = new byte[in.available()];
            in.read(data);
            in.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<ModelTreeDto> getModelTreeData(String modelName, AgencyUserModel user) {
        List<CompanyModel> companyList = user.getCompanys();
        List<ModelTreeDto> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(companyList)) {
            String companyName = companyList.get(0).getCompanyName();
            String orgCode = companyList.get(0).getOrgCode();

            List<ModelItem> listByName = modelItemMapper.getListByName(modelName, orgCode);
            if (!CollectionUtils.isEmpty(listByName)) {
                Map<String, List<ModelItem>> collect = listByName.stream().collect(Collectors.groupingBy(ModelItem::getModelName));
                collect.forEach((key, value) -> {
                    ModelTreeDto modelTreeDto = new ModelTreeDto();
                    modelTreeDto.setAmosOrgName(companyName);
                    modelTreeDto.setName(key);
                    modelTreeDto.setId(key);
                    List<Map<String, Object>> valueList = value.stream().map(e -> {
                        Map<String, Object> map = new HashMap<>(3);
                        map.put("data", e.getCheckItemValue());
                        map.put("id", e.getSequenceNbr());
                        map.put("name", e.getCheckItemLabel());
                        return map;
                    }).collect(Collectors.toList());
                    modelTreeDto.setChildren(valueList);
                    list.add(modelTreeDto);
                });
            }
        }
        return list;
    }

    @Override
    public List<CheckResult> getCheckItem(String modelName, AgencyUserModel userInfo) {
//        List<CompanyModel> companyList = userInfo.getCompanys();
//        List<CheckResult> resultList = new ArrayList<>();
//        if (!CollectionUtils.isEmpty(companyList)) {
//            String orgCode = companyList.get(0).getOrgCode();
//            resultList = checkResultMapper.getCheckItemNo(modelName, orgCode);
//        }
        return checkResultMapper.getCheckItemNo(modelName);
    }

    @Override
    public Map<String, Object> selectCheckItemTotal(String modelName, AgencyUserModel userInfo) {
        return checkResultMapper.selectCheckItemTotal(modelName);
    }
}
