package com.testor.module.emergency.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.controller.SysDictDataController;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataComplexResponse;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataListResponse;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataParam;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataRequest;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.module.emergency.dao.TContingencyPlanDao;
import com.testor.module.emergency.model.domain.SFunction;
import com.testor.module.emergency.model.domain.TContingencyPlan;
import com.testor.module.emergency.model.domain.TContingencyPlanContent;
import com.testor.module.emergency.model.domain.TContingencyPlanRecord;
import com.testor.module.emergency.model.dto.TContingencyPlanContentParam;
import com.testor.module.emergency.model.dto.TContingencyPlanDTO;
import com.testor.module.emergency.model.dto.TContingencyPlanParam;
import com.testor.module.emergency.model.vo.TContingency;
import com.testor.module.emergency.model.vo.TContingencyPlanContentVO;
import com.testor.module.emergency.model.vo.TContingencyPlanRecordVO;
import com.testor.module.emergency.model.vo.TContingencyPlanVO;
import com.testor.module.emergency.service.TContingencyPlanContentService;
import com.testor.module.emergency.service.TContingencyPlanRecordService;
import com.testor.module.emergency.service.TContingencyPlanService;
import com.testor.module.sys.service.TOrgService;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.supers.SuperModel;
import org.springframework.stereotype.Service;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 应急预案Service业务层处理
 *
 * @author testor-framework
 * @date 2022-10-18 09:50:43
 */
@Service
public class TContingencyPlanServiceImpl extends SuperServiceImpl<TContingencyPlanDao, TContingencyPlan> implements TContingencyPlanService {


    @Autowired(required = false)
    private TContingencyPlanDao tContingencyPlanDao;

    @Autowired
    private TContingencyPlanRecordService tContingencyPlanRecordService;

    @Autowired
    private TContingencyPlanContentService tContingencyPlanContentService;

    @Autowired
    private SysDictDataController sysDictDataController;

    @Autowired
    private SysDictDataService sysDictDataService;

    @Autowired
    private TOrgService tOrgService;


    @Override
    public Boolean addEntity(TContingencyPlanDTO tContingencyPlanDTO) {
        //新增
        String orgId = ContextUtils.getLoginUser().getOrgId();
        if (ObjectUtil.isEmpty(tContingencyPlanDTO.getTContingencyPlan().getId())) {

            List<String> accidentList = tContingencyPlanDTO.getTContingencyPlan().getAccidentList();
            TContingencyPlan tContingencyPlan = tContingencyPlanDTO.getTContingencyPlan();
            tContingencyPlan.setAccidentKey(JSONObject.toJSONString(accidentList));
            tContingencyPlan.setOrgId(orgId);
            Date reviseTime = tContingencyPlan.getReviseTime();
            //获取失效时间
            DateTime dateTime = DateUtil.offsetMonth(reviseTime, 36);
            tContingencyPlan.setDisabledTime(dateTime);
            boolean save = save(tContingencyPlan);
            String tContingencyPlanId = tContingencyPlan.getId();
            List<TContingencyPlanContentParam> tContingencyPlanContentParamList = tContingencyPlanDTO.getTContingencyPlanContentParamList();
            tContingencyPlanContentService.saveBatch(tContingencyPlanContentParamList.stream().map(tContingencyPlanContentParam -> {
                //    tContingencyPlanContentParam.setSpecificWork(JSONObject.toJSONString(tContingencyPlanContentParam.getSpecificWorkList()));
                tContingencyPlanContentParam.setPlanId(tContingencyPlanId);
                return tContingencyPlanContentParam;
            }).collect(Collectors.toList()));

            TContingencyPlanRecord tContingencyPlanRecord = tContingencyPlanDTO.getTContingencyPlanRecord();
            tContingencyPlanRecord.setOrgId(orgId);
            tContingencyPlanRecord.setPlanId(tContingencyPlanId);
            tContingencyPlanRecordService.save(tContingencyPlanRecord);
            //修改
        } else {
            String tContingencyPlanId = tContingencyPlanDTO.getTContingencyPlan().getId();
            List<String> accidentList = tContingencyPlanDTO.getTContingencyPlan().getAccidentList();
            TContingencyPlan tContingencyPlan = tContingencyPlanDTO.getTContingencyPlan();
            tContingencyPlan.setAccidentKey(JSONObject.toJSONString(accidentList));
            Date nowDate = new Date();
            tContingencyPlan.setReviseTime(nowDate);
            updateById(tContingencyPlan);
            List<TContingencyPlanContentParam> tContingencyPlanContentParamList = tContingencyPlanDTO.getTContingencyPlanContentParamList();
            Map<Boolean, List<TContingencyPlanContent>> isEmptyMap = tContingencyPlanContentParamList.stream().map(tContingencyPlanContentParam -> {
                //    tContingencyPlanContentParam.setSpecificWork(JSONObject.toJSONString(tContingencyPlanContentParam.getSpecificWorkList()));
                tContingencyPlanContentParam.setOrgId(orgId);
                tContingencyPlanContentParam.setPlanId(tContingencyPlanId);
                return BeanUtil.copyProperties(tContingencyPlanContentParam, TContingencyPlanContent.class);
            }).collect(Collectors.partitioningBy(tContingencyPlanContent -> ObjectUtil.isEmpty(tContingencyPlanContent.getId())));
            //id为空的保存
            LambdaUpdateWrapper<TContingencyPlanContent> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(TContingencyPlanContent::getPlanId, tContingencyPlanId).set(SuperModel::getStatus, 1);
            tContingencyPlanContentService.update(wrapper);
            tContingencyPlanContentService.saveBatch(isEmptyMap.get(true));
            TContingencyPlanRecord tContingencyPlanRecord = tContingencyPlanDTO.getTContingencyPlanRecord();
            tContingencyPlanRecord.setOrgId(orgId);
            tContingencyPlanRecord.setPlanId(tContingencyPlanId);
            tContingencyPlanRecordService.save(tContingencyPlanRecord);
        }
        return true;
    }

    @Override
    public TContingency getParticulars(String id) {
        TContingencyPlan tContingencyPlan = getById(id);
        TContingencyPlanVO tContingencyPlanVO = BeanUtil.copyProperties(tContingencyPlan, TContingencyPlanVO.class);
        tContingencyPlanVO.setAccidentList(JSONObject.parseObject(tContingencyPlanVO.getAccidentKey(), List.class));
        dictTranslate(tContingencyPlanVO, TContingencyPlanVO::getPlanTypeKey, TContingencyPlanVO::setPlanTypeName, "646b2313e3d34beab35e9e46f39a20eb");
        dictTranslateS(tContingencyPlanVO, TContingencyPlan::getAccidentKey, TContingencyPlanVO::setAccidentNameList, "45f23cfa2ff1415ea45d857aa249f66c");
        //查询工作组详情

        List<TContingencyPlanContentVO> tContingencyPlanContentList = tContingencyPlanContentService.getList(id);

        List<TContingencyPlanContentVO> tContingencyPlanContentVOList = tContingencyPlanContentList.stream().map(tContingencyPlanContent -> {
            TContingencyPlanContentVO tContingencyPlanContentVO = BeanUtil.copyProperties(tContingencyPlanContent, TContingencyPlanContentVO.class);
//            String specificWork = tContingencyPlanContentVO.getSpecificWork();
//            List list = JSONObject.parseObject(specificWork, List.class);
//            ArrayList<String> strings = new ArrayList<>();
//            for (Object o : list) {
//                strings.add((String) o);
//            }
            //     tContingencyPlanContentVO.setSpecificWorkList(strings);
            return tContingencyPlanContentVO;
        }).collect(Collectors.toList());

        //查询附件
        List<TContingencyPlanRecord> tContingencyPlanRecordList = tContingencyPlanRecordService.list(
                new LambdaQueryWrapper<TContingencyPlanRecord>()
                        .eq(TContingencyPlanRecord::getPlanId, id)
                        .eq(SuperModel::getStatus, 0).orderByDesc(SuperModel::getCreateDate)
        );
        TContingency tContingency = new TContingency();
        tContingency.setTContingencyPlanVO(tContingencyPlanVO);
        tContingency.setTContingencyPlanContentVOList(tContingencyPlanContentVOList);

        tContingency.setTContingencyPlanRecord(tContingencyPlanRecordList.get(0));
        return tContingency;
    }

    @Override
    public Page<TContingencyPlanVO> pageList(TContingencyPlanParam param) {
        Page<TContingencyPlanVO> page = new Page<>();
        if (ObjectUtil.isNotEmpty(param.getPage()) && ObjectUtil.isNotEmpty(param.getLimit())) {
            page.setCurrent(param.getPage());
            page.setSize(param.getLimit());
        } else {
            page.setCurrent(-1);
            page.setSize(-1);
        }

        if (ObjectUtil.isNotEmpty(param.getOrgIds())) {
            String[] split = param.getOrgIds().split(",");
            List<String> strings = Arrays.asList(split);
            param.setOrgIdList(strings);
        }
        String orgId = ContextUtils.getLoginUser().getOrgId();
        param.setOrgId(orgId);
        page = tContingencyPlanDao.pageList(page, param);
        List<TContingencyPlanVO> records = page.getRecords();
        for (TContingencyPlanVO record : records) {
            SysOrg regionalCompany = tOrgService.getRegionalCompany(record.getOrgId());
            if (regionalCompany != null) {
                record.setBusinessOrgName(regionalCompany.getOrgName());
            }
        }
        dictTranslate(records, TContingencyPlanVO::getPlanTypeKey, TContingencyPlanVO::setPlanTypeName, "PLAN_TYPE");
        page.setRecords(records);
        return page;

    }

    @Override
    public List<TContingencyPlanRecordVO> getEditHistory(String id) {
        List<TContingencyPlanRecordVO> list = tContingencyPlanRecordService.getEditHistory(id);
//                list(
//                new LambdaQueryWrapper<TContingencyPlanRecord>().eq(TContingencyPlanRecord::getPlanId, id)
//                        .eq(SuperModel::getStatus, 0)
//        );

        return list;
    }

    @Override
    public List<TContingencyPlanVO> listEntity(String simulationEventType) {
        String[] split = simulationEventType.split(",");
        simulationEventType = JSONObject.toJSONString(split);
        String orgId = ContextUtils.getLoginUser().getOrgId();
        //获取预案
        List<TContingencyPlan> tContingencyPlans = list(new LambdaQueryWrapper<TContingencyPlan>().eq(SuperModel::getStatus, "0")
                .eq(TContingencyPlan::getOrgId, orgId)
                //todo mysql 函数
                //.apply(simulationEventType != null,"JSON_CONTAINS(accident_key, '"+simulationEventType+"')")
                // kingbase 函数 AND accident_key::jsonb @> '["8","1"]'
                .apply(simulationEventType != null,"accident_key::jsonb @> '"+simulationEventType+"'")
        );
        List<TContingencyPlanVO> collect = tContingencyPlans.stream().map(tContingencyPlan -> {
            return BeanUtil.copyProperties(tContingencyPlan, TContingencyPlanVO.class);
        }).collect(Collectors.toList());
        dictTranslate(collect, TContingencyPlan::getPlanTypeKey, TContingencyPlanVO::setPlanTypeName, "PLAN_TYPE");
        Map<String, List<TContingencyPlanVO>> typeMap = collect.stream().collect(Collectors.groupingBy(TContingencyPlanVO::getPlanTypeName));

        ArrayList<TContingencyPlanVO> tContingencyPlanVOS = new ArrayList<>();
        for (String s : typeMap.keySet()) {
            TContingencyPlanVO tContingencyPlanVO = new TContingencyPlanVO();
            tContingencyPlanVO.setPlanTypeName(s);
            tContingencyPlanVO.setTContingencyPlanVOList(typeMap.get(s));
            tContingencyPlanVOS.add(tContingencyPlanVO);
        }

        return tContingencyPlanVOS;
    }


    public <T> void dictTranslate(Collection<T> entities, Function<T, String> getKey, SFunction<T, String> setValue, String dictType) {
        if (Objects.isNull(entities) || entities.isEmpty()) {
            return;
        }

        Set<String> keys = new HashSet<>();


        for (T x : entities) {
            String deptId = getKey.apply(x);
            if (Objects.nonNull(deptId)) {
                keys.add(deptId);
            }
        }
        if (ObjectUtil.isEmpty(keys)) {
            log.warn("字典没有当前值");
            return;
        }
        SysDictDataRequest sysDictDataRequest = new SysDictDataRequest();
        sysDictDataRequest.setDictType(dictType);
        BaseResponse<SysDictDataComplexResponse> sysDictDataComplexResponseBaseResponse = sysDictDataController.listDataByType(sysDictDataRequest);
        List<SysDictDataListResponse> data = sysDictDataComplexResponseBaseResponse.getData().getData();
        Map<String, String> dictMap = data.stream().collect(Collectors.toMap(SysDictDataListResponse::getDictKey, SysDictDataListResponse::getDictValue));

        entities = entities.stream().map(entity -> {
            String apply = getKey.apply(entity);
            if (apply != null) {
                String deptName = dictMap.get(apply);
                if (ObjectUtil.isNotEmpty(deptName)) {
                    setValue.set(entity, deptName);
                } else {
                    setValue.set(entity, "");
                }

            } else {
                setValue.set(entity, "");
            }

            return entity;
        }).collect(Collectors.toList());
    }


    public <T> void dictTranslate(T entity, Function<T, String> getKey, SFunction<T, String> setValue, String id) {
        SysDictDataParam sysDictDataParam = new SysDictDataParam();
        sysDictDataParam.setDictId(id);
        BaseResponse<BaseResponseList<SysDictDataListResponse>> baseResponseListBaseResponse = sysDictDataController.listAllEntity(sysDictDataParam);
        List<SysDictDataListResponse> data = baseResponseListBaseResponse.getData().getData();
        Map<String, String> dictMap = data.stream().collect(Collectors.toMap(SysDictDataListResponse::getDictKey, SysDictDataListResponse::getDictValue));
        String apply = getKey.apply(entity);
        String s = dictMap.get(apply);
        setValue.set(entity, s);
    }

    public <T> void dictTranslateS(T entity, Function<T, String> getKey, SFunction<T, List<String>> setValue, String id) {
        SysDictDataParam sysDictDataParam = new SysDictDataParam();
        sysDictDataParam.setDictId(id);
        BaseResponse<BaseResponseList<SysDictDataListResponse>> baseResponseListBaseResponse = sysDictDataController.listAllEntity(sysDictDataParam);
        List<SysDictDataListResponse> data = baseResponseListBaseResponse.getData().getData();
        Map<String, String> dictMap = data.stream().collect(Collectors.toMap(SysDictDataListResponse::getDictKey, SysDictDataListResponse::getDictValue));
        String apply = getKey.apply(entity);
        ArrayList<String> strings = new ArrayList<>();
        for (String s : apply.split("\\|")) {
            String s1 = dictMap.get(s);
            if (ObjectUtil.isNotEmpty(s1)) {
                strings.add(s1);
            }
        }
        setValue.set(entity, strings);
    }


    public static void main(String[] args) {
        String simulationEventType = "1,2,3";
        String[] split = simulationEventType.split(",");
        simulationEventType = JSONObject.toJSONString(split);
        System.out.println(simulationEventType  );
    }
}
