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

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.testor.biz.sys.dict.DictEnumCode;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
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.dict.type.model.domain.SysDictType;
import com.testor.biz.sys.dict.type.service.SysDictTypeService;
import com.testor.common.constant.StatusEnum;
import com.testor.module.fives.dao.TFivesStandardDao;
import com.testor.module.fives.model.domain.TFivesStandard;
import com.testor.module.fives.model.domain.TFivesSubOption;
import com.testor.module.fives.model.dto.TFivesStandardDTO;
import com.testor.module.fives.model.dto.TFivesStandardDelParam;
import com.testor.module.fives.model.dto.TFivesStandardReportDTO;
import com.testor.module.fives.model.dto.TFivesSubOptionDTO;
import com.testor.module.fives.model.excel.TFivesStandardReport;
import com.testor.module.fives.service.TFivesStandardService;
import com.testor.module.fives.service.TFivesSubOptionService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.exceptions.ApiException;
import com.tongtech.tfw.backend.common.models.response.ResponseInfo;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 5s标准验收管理Service业务层处理
 *
 * @author testor-framework
 * @date 2022-07-11 14:00:17
 */
@Service("tFivesStandardServiceImpl")
public class TFivesStandardServiceImpl extends SuperServiceImpl<TFivesStandardDao, TFivesStandard> implements TFivesStandardService {
    @Autowired(required = false)
    private TFivesStandardDao tFivesStandardDao;

    @Autowired(required = false)
    private TFivesSubOptionService tFivesSubOptionService;

    @Autowired
    private SysDictTypeService sysDictTypeService;
    @Autowired
    private SysDictDataService sysDictDataService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse<String> add(TFivesStandardDTO tFivesStandardDTO) {
        BaseResponse<String> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isEmpty(tFivesStandardDTO)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数为空");
            return baseResponse;
        }

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }

        // 当前用户所属组织机构id
        String orgId = curUser.getOrgId();
        // 标准类型
        String standardType = tFivesStandardDTO.getStandardType();
        // 分项
        String subOption = tFivesStandardDTO.getSubOption();
        // 子项
        String child = tFivesStandardDTO.getChild();

        boolean judgeRepeat = judgeRepeat(standardType, subOption, child, orgId, null);
        if (judgeRepeat) {
            // 已存在该子项内容，请选择其他子项
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("已存在该子项内容，请选择其他子项");
            return baseResponse;
        }

        String fiveStandardId = IdHelper.getId32bit();
        TFivesStandard data = BeanHelper.beanToBean(tFivesStandardDTO, TFivesStandard.class);
        data.setId(fiveStandardId);
        data.setOrgId(orgId);

        List<TFivesSubOptionDTO> addSubOptionList = new ArrayList<>();
        // 一级
        List<TFivesSubOptionDTO> levelOne = tFivesStandardDTO.getLevelOne();

        Map<String, String> judgeNameRepeat = new HashMap<>();
        for (TFivesSubOptionDTO tFivesSubOptionDTOLevelOne : levelOne) {

            String name = tFivesSubOptionDTOLevelOne.getName();
            if (null != judgeNameRepeat.get(name)) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("主要内容填写不能重复");
                return baseResponse;
            } else {
                judgeNameRepeat.put(name, name);
            }

            String levelOneId = IdHelper.getId32bit();
            tFivesSubOptionDTOLevelOne.setParentId(fiveStandardId);
            tFivesSubOptionDTOLevelOne.setId(levelOneId);
            tFivesSubOptionDTOLevelOne.setParentId(fiveStandardId);
            tFivesSubOptionDTOLevelOne.setOrgId(orgId);
            tFivesSubOptionDTOLevelOne.setStatus(StatusEnum.USE.getCode());
            tFivesSubOptionDTOLevelOne.setContentType("1");
            // 二级
            List<TFivesSubOptionDTO> levelTow = tFivesSubOptionDTOLevelOne.getLevelTow();
            levelTow.forEach(action -> {
                action.setParentId(fiveStandardId);
                String levelTowId = IdHelper.getId32bit();
                action.setId(levelTowId);
                action.setOrgId(orgId);
                action.setStatus(StatusEnum.USE.getCode());
                action.setSubId(levelOneId);
                action.setContentType("2");

            });
            addSubOptionList.addAll(levelTow);
            addSubOptionList.add(tFivesSubOptionDTOLevelOne);
        }

        List<TFivesSubOption> tFivesSubOptions = BeanHelper.listToList(addSubOptionList, TFivesSubOption.class);
        boolean saveSubOptions = tFivesSubOptionService.saveBatch(tFivesSubOptions);

        boolean result = save(data);
        if (!result || !saveSubOptions) {
            throw new ApiException(new ResponseInfo(BaseStatusEnum.UN_DATA.code(), "5s标准验收管理添加失败"));
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<String> update(TFivesStandardDTO tFivesStandardDTO) {
        BaseResponse<String> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isEmpty(tFivesStandardDTO)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数为空");
            return baseResponse;
        }

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }

        String fiveStandardId = tFivesStandardDTO.getId();
        // 当前用户所属组织机构id
        String orgId = curUser.getOrgId();
        // 标准类型
        String standardType = tFivesStandardDTO.getStandardType();
        // 分项
        String subOption = tFivesStandardDTO.getSubOption();
        // 子项
        String child = tFivesStandardDTO.getChild();

        boolean judgeRepeat = judgeRepeat(standardType, subOption, child, orgId, fiveStandardId);
        if (judgeRepeat) {
            // 已存在该子项内容，请选择其他子项
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("已存在该子项内容，请选择其他子项");
            return baseResponse;
        }

        TFivesStandard tFivesStandard = BeanHelper.beanToBean(tFivesStandardDTO, TFivesStandard.class);

        List<TFivesSubOptionDTO> addSubOptionList = new ArrayList<>();
        // 一级
        List<TFivesSubOptionDTO> levelOne = tFivesStandardDTO.getLevelOne();
        Map<String, String> judgeNameRepeat = new HashMap<>();

        for (TFivesSubOptionDTO tFivesSubOptionDTOLevelOne : levelOne) {

            String name = tFivesSubOptionDTOLevelOne.getName();
            if (null != judgeNameRepeat.get(name)) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("主要内容填写不能重复");
                return baseResponse;
            } else {
                judgeNameRepeat.put(name, name);
            }

            String levelOneId = IdHelper.getId32bit();
            tFivesSubOptionDTOLevelOne.setParentId(fiveStandardId);
            tFivesSubOptionDTOLevelOne.setId(levelOneId);
            tFivesSubOptionDTOLevelOne.setParentId(fiveStandardId);
            tFivesSubOptionDTOLevelOne.setOrgId(orgId);
            tFivesSubOptionDTOLevelOne.setStatus(StatusEnum.USE.getCode());
            tFivesSubOptionDTOLevelOne.setContentType("1");
            // 二级
            List<TFivesSubOptionDTO> levelTow = tFivesSubOptionDTOLevelOne.getLevelTow();
            levelTow.forEach(action -> {
                action.setParentId(fiveStandardId);
                String levelTowId = IdHelper.getId32bit();
                action.setId(levelTowId);
                action.setOrgId(orgId);
                action.setStatus(StatusEnum.USE.getCode());
                action.setSubId(levelOneId);
                action.setContentType("2");

            });
            addSubOptionList.addAll(levelTow);
            addSubOptionList.add(tFivesSubOptionDTOLevelOne);
        }

        List<TFivesSubOption> tFivesSubOptions = BeanHelper.listToList(addSubOptionList, TFivesSubOption.class);
        boolean delSubOption = delSubOption(fiveStandardId);
        boolean saveSubOptions = tFivesSubOptionService.saveBatch(tFivesSubOptions);
        boolean updateStandard = updateById(tFivesStandard);
        if (!updateStandard || !saveSubOptions || !delSubOption) {
            throw new ApiException(new ResponseInfo(BaseStatusEnum.UN_DATA.code(), "5s标准验收管理修改失败"));
        }
        return baseResponse;
    }

    @Override
    public List<TFivesStandardReport> exportFiveStandard(String dsName, String datasetName, Map<String, Object> parameters) {

        Map<String, List<SysDictDataListResponse>> map = new HashMap<>(16);

        String s = JSON.toJSONString(parameters);
        TFivesStandardReportDTO param = JSONObject.parseObject(s, TFivesStandardReportDTO.class);

        List<TFivesStandardReport> tFivesStandardReports = tFivesStandardDao.exportFiveStandard(param);


        tFivesStandardReports.forEach(action -> {
            // 一级
            String standardType = action.getStandardType();
            List<SysDictDataListResponse> levelOne = map.get(standardType);
            String s3 = getDictValue(levelOne, standardType, map, "5S_ACCEPTANCE_STANDARD_TYPE");
            action.setStandardType(s3);

            // 二级
            String subOption = action.getSubOption();
            List<SysDictDataListResponse> levelTow = map.get(subOption);
            String s1 = getDictValue(levelTow, subOption, map, standardType);
            action.setSubOption(s1);

            // 三级
            String child = action.getChild();
            List<SysDictDataListResponse> levelThree = map.get(child);
            String s2 = getDictValue(levelThree, child, map, subOption);
            action.setChild(s2);
        });
        System.err.println(tFivesStandardReports);
        return tFivesStandardReports;
    }

    @Override
    public String getDictValue(List<SysDictDataListResponse> list, String type, Map<String, List<SysDictDataListResponse>> map, String dictType) {

        if (StrUtil.isEmpty(dictType)) {
            return null;
        }
        if (null == list || list.size() == 0) {
            List<SysDictDataListResponse> dict = getDict(dictType);
            for (SysDictDataListResponse sysDictDataListResponse : dict) {
                String dictKey = sysDictDataListResponse.getDictKey();
                if (type.equals(dictKey)) {
                    map.put(type, dict);
                    return sysDictDataListResponse.getDictValue();
                }
            }
        } else {
            for (SysDictDataListResponse sysDictDataListResponse : list) {
                String dictKey = sysDictDataListResponse.getDictKey();
                if (type.equals(dictKey)) {
                    return sysDictDataListResponse.getDictValue();
                }
            }
        }

        return null;
    }

    public List<SysDictDataListResponse> getDict(String standardType) {
        SysDictDataRequest sysDictDataRequest = new SysDictDataRequest();
        sysDictDataRequest.setDictType(standardType);
        return listDataByType(sysDictDataRequest);
    }

    public List<SysDictDataListResponse> listDataByType(SysDictDataRequest param) {
        if (StringHelper.isEmpty(param.getDictType())) {
            throw new ApiException(DictEnumCode.UN_DICT_TYPE_PARAM.transform());
        } else {
            QueryWrapper<SysDictType> sysDictTypeQueryWrapper = new QueryWrapper<>();
            sysDictTypeQueryWrapper.eq("dict_type", param.getDictType());
            sysDictTypeQueryWrapper.eq("status", "0");
            SysDictType sysDictType = sysDictTypeService.getOne(sysDictTypeQueryWrapper);
//            SysDictType sysDictType = sysDictTypeService.getOne((Wrapper) ((LambdaQueryWrapper) ((LambdaQueryWrapper) (new ).lambda().eq(SysDictType::getDictType, param.getDictType())).eq(SuperModel::getStatus, "0")).last("LIMIT 1"));
            if (ObjectHelper.isEmpty(sysDictType)) {
                throw new ApiException(DictEnumCode.UN_DICT_TYPE.transform());
            } else {
                SysDictDataParam sysDictDataParam = new SysDictDataParam();
                sysDictDataParam.setDictId(sysDictType.getDictId());
                sysDictDataParam.setOrderBy("tree_sort");
                sysDictDataParam.setOrderType("asc");
                QueryWrapper<SysDictData> queryWrapper = createQueryDict(sysDictDataParam);
                return this.sysDictDataService.list(queryWrapper).stream().map((e) -> {
                    return e.beanToBean(SysDictDataListResponse.class);
                }).collect(Collectors.toList());
            }
        }
    }

    private QueryWrapper<SysDictData> createQueryDict(SysDictDataParam queryParam) {
        QueryWrapper<SysDictData> queryWrapper = new QueryWrapper<>();
        if (StringHelper.isNotEmpty(queryParam.getDictId())) {
            queryWrapper.eq("dict_id", queryParam.getDictId());
        }

        if (StringHelper.isNotEmpty(queryParam.getStatus())) {
            queryWrapper.eq("status", queryParam.getStatus());
        } else {
            queryWrapper.ne("status", "1");
        }

        if (StringHelper.isNotEmpty(queryParam.getOrderBy())) {
            if (StringHelper.isNotEmpty(queryParam.getOrderType()) && "asc".equals(queryParam.getOrderType())) {
                queryWrapper.orderByAsc(queryParam.getOrderBy());
            } else {
                queryWrapper.orderByDesc(queryParam.getOrderBy());
            }
        } else {
            queryWrapper.orderByDesc("tree_sort");
        }

        return queryWrapper;
    }

    /**
     * 重复判断，判断现有列表数据，【标准类型】+【分项】+【子项】均相同，为重复，提示：已存在该子项内容，请选择其他子项
     *
     * @param standardType 标准类型
     * @param subOption    分项
     * @param child        子项
     * @param orgId        所属组织结构id
     * @return ture-存在/false-不存在
     */
    private boolean judgeRepeat(String standardType, String subOption, String child, String orgId, String id) {
        QueryWrapper<TFivesStandard> tFivesStandard = new QueryWrapper<>();
        tFivesStandard.eq("standard_type", standardType);
        tFivesStandard.eq("sub_option", subOption);
        tFivesStandard.eq("child", child);
        tFivesStandard.eq("org_id", orgId);
        tFivesStandard.eq("status", StatusEnum.USE.getCode());
        TFivesStandard one = getOne(tFivesStandard);
        if (ObjectHelper.isEmpty(one)) {
            return false;
        } else {
            if (StrUtil.isNotEmpty(id)) {
                String fiveId = one.getId();
                return !fiveId.equals(id);
            }
        }
        return true;
    }

    @Override
    public boolean delSubOption(String fiveStandardId) {

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            return false;
        }

        TFivesSubOption tFivesSubOption = new TFivesSubOption();
        tFivesSubOption.setStatus(StatusEnum.DELETE.getCode());
        tFivesSubOption.setUpdateDate(new Date());
        tFivesSubOption.setUpdateBy(curUser.getUserId());
        QueryWrapper<TFivesSubOption> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", fiveStandardId);
        return tFivesSubOptionService.update(tFivesSubOption, queryWrapper);
    }

    @Override
    public BaseResponse<String> deleteEntity(TFivesStandardDelParam deleteRequest) {
        BaseResponse<String> baseResponse = new BaseResponse<>();
        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        if (ObjectHelper.isNotEmpty(deleteRequest) && StringHelper.isNotEmpty(deleteRequest.getId())) {
            TFivesStandard data = new TFivesStandard();
            data.setId(deleteRequest.getId());
            data.setStatus(BizConstants.STATUS_DELETE);
            data.setUpdateBy(curUser.getUserId());
            data.setUpdateDate(new Date());
            boolean result = updateById(data);
            boolean delSubOption = delSubOption(deleteRequest.getId());
            if (result && delSubOption) {
                baseResponse.setMsg("5s标准验收管理删除成功");
            } else {
                throw new ApiException(new ResponseInfo(BaseStatusEnum.UN_DATA.code(), "5s标准验收管理删除失败"));
            }
        }
        return baseResponse;
    }
}
