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

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.common.api.dto.*;
import com.yeejoin.amos.boot.module.jyjc.api.entity.JyjcInspectionApplication;
import com.yeejoin.amos.boot.module.jyjc.api.entity.JyjcInspectionApplicationEquip;
import com.yeejoin.amos.boot.module.jyjc.api.mapper.*;
import com.yeejoin.amos.boot.module.jyjc.api.model.JyjcInspectionApplicationModel;
import com.yeejoin.amos.boot.module.statistics.api.mapper.JYJCStatisticsMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.parseArray;

/**
 * 大屏统计实现类
 *
 * @author Administrator
 */
@Service
@Slf4j
public class InspectionBizServiceImpl {


    private JyjcInspectionApplicationEquipMapper inspectionApplicationEquipMapper;

    private ESEquipmentCategory esEquipmentCategoryDao;

    private JyjcInspectionApplicationMapper inspectionApplicationMapper;

    private JyjcInspectionApplicationAttachmentMapper inspectionApplicationAttachmentMapper;

    private WorkflowFeignService workflowFeignService;

    private JyjcInspectionApplicationEquipMapper jyjcInspectionApplicationEquipMapper;

    @Value("classpath:/json/bigScreenDetail.json")
    private Resource bigScreenDetail;

    public InspectionBizServiceImpl(JyjcInspectionApplicationEquipMapper inspectionApplicationEquipMapper, ESEquipmentCategory esEquipmentCategoryDao, JyjcInspectionApplicationMapper inspectionApplicationMapper, JyjcInspectionApplicationAttachmentMapper inspectionApplicationAttachmentMapper, WorkflowFeignService workflowFeignService, JyjcInspectionApplicationEquipMapper jyjcInspectionApplicationEquipMapper) {
        this.inspectionApplicationEquipMapper = inspectionApplicationEquipMapper;
        this.esEquipmentCategoryDao = esEquipmentCategoryDao;
        this.inspectionApplicationMapper = inspectionApplicationMapper;
        this.inspectionApplicationAttachmentMapper = inspectionApplicationAttachmentMapper;
        this.workflowFeignService = workflowFeignService;
        this.jyjcInspectionApplicationEquipMapper = jyjcInspectionApplicationEquipMapper;
    }


    public Map<String, Object> selectOneForBigScreen(Long sequenceNbr, String companyType) {
        JyjcInspectionApplicationModel model = inspectionApplicationMapper.selectDataBySeq(sequenceNbr);
        Map<String, Object> map = BeanUtil.beanToMap(model);
        // 附件
        Map<String, Object> attMap = getAttachmentMap(sequenceNbr);
        // 设备
        List<Map<String, Object>> arrayList = getEquipInfoList(sequenceNbr);
        map.put("equip", arrayList);
        map.putAll(attMap);
        map.put("companyType", companyType);
        this.setPlanData(sequenceNbr, map);

        Map<String,Object> resultMap = new HashMap<>();
        Map<String, Object> workflowResult = workflowFeignService.getFlowLogger(model.getProcessInstanceId()).getResult();
        ArrayList<Map<String, Object>> flowLogger = (ArrayList) workflowResult.get("flowLogger");
        ArrayList<Map<String, Object>> records = new ArrayList<>();

        List<FormValue> jsonData = getJsonData(bigScreenDetail);
        jsonData.forEach(f -> {
            Object o = map.get(f.getKey());
            if (!org.apache.commons.lang3.ObjectUtils.isEmpty(o)) {
                if (f.getKey().equals("applicationDate")){
                    try {
                        f.setValue(org.typroject.tyboot.core.foundation.utils.DateUtil.formatDate((Date) o, org.typroject.tyboot.core.foundation.utils.DateUtil.Y_M_D));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    f.setValue(o.toString());
                }
            }
        });

        if(!CollectionUtils.isEmpty(flowLogger)){
            for(int i = flowLogger.size()-1;i>=0;i--){
                HashMap<String, Object> data = new HashMap<>();
                data.put("label", flowLogger.get(i).get("approvalStatue"));
                data.put("operatingTime", flowLogger.get(i).get("operateDate"));
                if(null != flowLogger.get(i).get("assignee")) {
                    data.put("operater", ((Map<String, Object>) flowLogger.get(i).get("assignee")).get("orgNamesWithoutRole") + "【" + flowLogger.get(i).get("taskName") + "】");
                }else if(null != flowLogger.get(i).get("companyName")){
                    data.put("operater", flowLogger.get(i).get("companyName") + "【" + flowLogger.get(i).get("taskName") + "】");
                }
                records.add(data);
            }
        }
        HashMap<String, Object> datas = new HashMap<>();
        datas.put("datas", records);
        datas.put("title", "审批进度");
        datas.put("renderType", "timeline");
        resultMap.put("title", map.get("applicationUnitName"));
        resultMap.put("infoRecords", datas);
        resultMap.put("keyParams", jsonData);
        return resultMap;
    }

    private List<FormValue> getJsonData(Resource resource) {
        String json;
        try {
            json = IOUtils.toString(resource.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return parseArray(json, FormValue.class);
    }

    public Page selectOneForBigScreenEqu(int current, int size, Long sequenceNbr, String companyType) {
        // 设备
        List<Map<String, Object>> arrayList = getEquipInfoList(sequenceNbr);
        Page<Map<String, Object>> page = new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        page.setTotal(arrayList.size());
        page.setRecords(arrayList.subList((current - 1) * size, arrayList.size() > current * size ? current * size : arrayList.size()));
        return page;
    }
    private List<Map<String, Object>> getEquipInfoList(Long sequenceNbr) {
        Iterable<ESEquipmentCategoryDto> equips = getEsEquipmentCategoryDtos(sequenceNbr);
        return getEquipListMaps(equips);
    }

    private List<Map<String, Object>> getEquipListMaps(Iterable<ESEquipmentCategoryDto> equips) {
        List<Map<String, Object>> arrayList = new ArrayList<>();
        equips.forEach(equip -> {
            Map<String, Object> objectHashMap = new HashMap<>();
            BeanUtil.beanToMap(equip, objectHashMap, false, false);
            objectHashMap.put("record", equip.getSEQUENCE_NBR());
            objectHashMap.put("ADDRESS", concatDetailAddress(equip));
            arrayList.add(objectHashMap);
        });
        return arrayList;
    }

    private String concatDetailAddress(ESEquipmentCategoryDto esEquipmentCategoryDto) {
        // 省、市、区
        String usePlace = esEquipmentCategoryDto.getUSE_PLACE();
        // 详细地址
        String address = esEquipmentCategoryDto.getADDRESS();
        return String.format("%s%s", usePlace, address);
    }

    private Iterable<ESEquipmentCategoryDto> getEsEquipmentCategoryDtos(Long sequenceNbr) {
        LambdaQueryWrapper<JyjcInspectionApplicationEquip> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(JyjcInspectionApplicationEquip::getApplicationSeq, sequenceNbr);
        wrapper.select(JyjcInspectionApplicationEquip::getEquipUnicode);
        List<JyjcInspectionApplicationEquip> jyjcInspectionApplicationEquips = jyjcInspectionApplicationEquipMapper.selectList(wrapper);
        List<String> records = jyjcInspectionApplicationEquips.stream().map(JyjcInspectionApplicationEquip::getEquipUnicode).distinct().collect(Collectors.toList());
        return esEquipmentCategoryDao.findAllById(records);
    }

    private void setPlanData(Long sequenceNbr, Map<String, Object> map) {
        JSONObject planData = this.getDetail(String.valueOf(sequenceNbr));
        map.put("planData", planData);
    }

    private String getOneEquipAddress(String applicationSeq) {
        // 查询报检的设备，返回地址，目前是单台报检，applicationEquips长度只有1，后续会多个
        List<JyjcInspectionApplicationEquip> applicationEquips = inspectionApplicationEquipMapper.selectList(new LambdaQueryWrapper<JyjcInspectionApplicationEquip>().eq(JyjcInspectionApplicationEquip::getApplicationSeq, applicationSeq));
        // 拼接地址
        List<String> allAddress = new ArrayList<>();
        applicationEquips.forEach(e -> {
            String record = e.getEquipUnicode();
            Optional<ESEquipmentCategoryDto> optional = esEquipmentCategoryDao.findById(record);
            if (optional.isPresent()) {
                ESEquipmentCategoryDto esEquipmentCategoryDto = optional.get();
                allAddress.add(this.concatDetailAddress(esEquipmentCategoryDto));
            }
        });
        return String.join(",", allAddress);
    }

    public JSONObject getDetail(String applicationSeq) {
        JyjcInspectionApplication inspectionApplication = inspectionApplicationMapper.selectById(applicationSeq);
        // 初始时查询设备地址关联设备表
        JSONObject jsonObject = inspectionApplication.getPlanData();
        if (jsonObject == null) {
            jsonObject = new JSONObject();
            String address = this.getOneEquipAddress(applicationSeq);
            jsonObject.put("address", address);
        }
        return jsonObject;
    }


    private Map<String, Object> getAttachmentMap(Long sequenceNbr) {
        List<Map<String, Object>> dataByApplicationSeq = inspectionApplicationAttachmentMapper.getDataByApplicationSeq(sequenceNbr);
        Map<String, Object> attMap = new HashMap<>();
        for (Map<String, Object> maps : dataByApplicationSeq) {
            List<AttachmentDto> data = JSONArray.parseArray(maps.get("attachment_url").toString(), AttachmentDto.class);
            attMap.put(maps.get("attachment_type").toString(), data);
        }
        return attMap;
    }

}
