package com.yunzhupaas.base.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.*;
import com.yunzhupaas.base.mapper.PrintDevMapper;
import com.yunzhupaas.base.model.dataset.DataSetForm;
import com.yunzhupaas.base.model.dataset.DataSetInfo;
import com.yunzhupaas.base.model.dataset.DataSetPagination;
import com.yunzhupaas.base.model.dataset.TableTreeModel;
import com.yunzhupaas.base.model.print.*;
import com.yunzhupaas.base.model.vo.PrintDevVO;
import com.yunzhupaas.base.service.*;
import com.yunzhupaas.base.util.dataSet.DataSetSwapUtil;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.emnus.DataSetTypeEnum;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.flowable.entity.RecordEntity;
import com.yunzhupaas.model.login.UserSystemVO;
import com.yunzhupaas.permission.entity.AuthorizeEntity;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.service.AuthorizeService;
import com.yunzhupaas.permission.service.PermissionGroupService;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.RandomUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import com.yunzhupaas.util.enums.DictionaryDataEnum;
import com.yunzhupaas.util.treeutil.SumTree;
import com.yunzhupaas.util.treeutil.newtreeutil.TreeDotUtils;
import com.yunzhupaas.workflow.service.TaskApi;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 打印模板-服务实现类
 *
 * @author 云筑产品开发平台组 YY
 * @version V3.2.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2024-09-30
 */
@Service
public class PrintDevServiceImpl extends SuperServiceImpl<PrintDevMapper, PrintDevEntity> implements PrintDevService {

    @Autowired
    private PrintVersionService printVersionService;
    
    @Autowired
    private DictionaryDataService dictionaryDataService;
    @Autowired
    private DictionaryTypeService dictionaryTypeService;
    @Autowired
    private UserService userService;
    @Autowired
    private DataSetService dataSetService;
    @Autowired
    private TaskApi taskApi;
    @Autowired
    private DataSetSwapUtil dataSetSwapUtil;
    @Autowired
    private AuthorizeService authorizeService;
    @Autowired
    private PermissionGroupService permissionGroupService;
    @Autowired
    private DataInterfaceService dataInterfaceService;

    @Override
    public List<PrintDevEntity> getList(PaginationPrint paginationPrint) {
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(paginationPrint.getKeyword())) {
            queryWrapper.lambda().and(
                    t -> t.like(PrintDevEntity::getFullName, paginationPrint.getKeyword())
                            .or().like(PrintDevEntity::getEnCode, paginationPrint.getKeyword())
            );
        }
        if (StringUtil.isNotEmpty(paginationPrint.getCategory())) {
            queryWrapper.lambda().eq(PrintDevEntity::getCategory, paginationPrint.getCategory());
        }
        if (paginationPrint.getState() != null) {
            queryWrapper.lambda().eq(PrintDevEntity::getState, paginationPrint.getState());
        }

        queryWrapper.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        Page<PrintDevEntity> page = new Page<>(paginationPrint.getCurrentPage(), paginationPrint.getPageSize());
        IPage<PrintDevEntity> iPage = this.page(page, queryWrapper);
        return paginationPrint.setData(iPage.getRecords(), page.getTotal());
    }

    @Override
    public void create(PrintDevFormDTO dto) {
        PrintDevEntity entity = JsonUtil.getJsonToBean(dto, PrintDevEntity.class);
        UserInfo userInfo = UserProvider.getUser();
        // 校验
        this.creUpdateCheck(entity, true, true);
        String id = StringUtil.isNotEmpty(entity.getId()) ? entity.getId() : RandomUtil.uuId();
        entity.setId(id);
        entity.setState(0);
        entity.setCreatorUserId(userInfo.getUserId());
        entity.setCreatorTime(new Date());
        entity.setLastModifyUserId(null);
        entity.setLastModifyTime(null);
        this.setIgnoreLogicDelete().removeById(entity.getId());
        this.setIgnoreLogicDelete().saveOrUpdate(entity);
        this.clearIgnoreLogicDelete();
        dto.setId(id);
        List<PrintVersionEntity> list = printVersionService.getList(id);
        if (CollectionUtils.isEmpty(list)) {
            printVersionService.create(dto);
        }
    }

    @Override
    public PrintDevInfoVO getVersionInfo(String versionId) {
        PrintVersionEntity versionEntity = printVersionService.getById(versionId);
        PrintDevEntity entity = this.getById(versionEntity.getTemplateId());
        PrintDevInfoVO vo = JsonUtil.getJsonToBean(entity, PrintDevInfoVO.class);
        vo.setVersionId(versionId);
        vo.setPrintTemplate(versionEntity.getPrintTemplate());
        vo.setConvertConfig(versionEntity.getConvertConfig());
        List<DataSetEntity> list = dataSetService.getList(new DataSetPagination(DataSetTypeEnum.PRINT_VER.getCode(), versionId));
        List<DataSetInfo> dataSetInfoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (DataSetEntity item : list) {
                DataSetInfo bean = JsonUtil.getJsonToBean(item, DataSetInfo.class);
                try {
                    SumTree<TableTreeModel> printTableFields = dataSetService.getTabFieldStruct(item);
                    bean.setChildren(printTableFields.getChildren());
                    dataSetInfoList.add(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (Objects.equals(item.getType(), 3)) {
                    DataInterfaceEntity info = dataInterfaceService.getInfo(item.getInterfaceId());
                    if (info != null) {
                        bean.setTreePropsName(info.getFullName());
                    }
                }
            }
        }
        vo.setDataSetList(dataSetInfoList);
        return vo;
    }

    @Override
    @Transactional
    public void saveOrRelease(PrintDevUpForm form) {
        PrintDevEntity entity = this.getById(form.getId());
        PrintVersionEntity versionNew = printVersionService.getById(form.getVersionId());
        //已归档
        boolean isDossier = false;
        if (Objects.equals(versionNew.getState(), 2) || Objects.equals(versionNew.getState(), 1)) {
            isDossier = !isDossier;
        }
        //发布
        if (Objects.equals(form.getType(), 1)) {
            //修改版本状态
            if (StringUtil.isNotEmpty(form.getVersionId())) {
                PrintVersionEntity info = printVersionService.getList(form.getId()).stream().filter(t -> Objects.equals(t.getState(), 1)).findFirst().orElse(null);
                if (info != null) {
                    // 变更归档状态，排序码
                    info.setSortCode(0L);
                    info.setState(2);
                    printVersionService.updateById(info);
                }
                versionNew.setState(1);
                versionNew.setSortCode(1L);
                //已发布
                if (Objects.equals(entity.getState(), 0)) {
                    entity.setState(1);
                }
            }
        }
        //已归档不修改设计内容和数据集内容
        if (!isDossier) {
            versionNew.setPrintTemplate(form.getPrintTemplate());
            versionNew.setConvertConfig(form.getConvertConfig());
            //数据集创建
            String versionId = versionNew.getId();
            List<DataSetForm> dataSetList = form.getDataSetList() != null ? form.getDataSetList() : new ArrayList<>();
            dataSetService.create(dataSetList, DataSetTypeEnum.PRINT_VER.getCode(), versionId);
        }
        printVersionService.updateById(versionNew);

        entity.setLastModifyTime(new Date());
        entity.setLastModifyUserId(UserProvider.getUser().getUserId());
        this.updateById(entity);
    }


    @Override
    public List<PrintDevVO> getTreeModel(String category) {
        QueryWrapper<PrintDevEntity> query = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(category)) {
            query.lambda().eq(PrintDevEntity::getCategory, category);
        }
        query.lambda().eq(PrintDevEntity::getState, 1);

        //不是通用
        query.lambda().and(t -> t.eq(PrintDevEntity::getCommonUse, 0).or().isNull(PrintDevEntity::getCommonUse));

        query.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        List<PrintDevEntity> printEntityList = this.list(query);
        return setTreeModel(printEntityList);
    }

    private List<PrintDevVO> setTreeModel(List<PrintDevEntity> printEntityList) {
        //数据字典缺失
        DictionaryTypeEntity DictionaryType = dictionaryTypeService.getInfoByEnCode(DictionaryDataEnum.SYSTEM_PRINTDEV.getDictionaryTypeId());
        if (DictionaryType == null) {
            throw new DataException(MsgCode.PRI002.get());
        }
        List<DictionaryDataEntity> dicDataList = dictionaryDataService.
                getList(DictionaryType.getId());
        List<PrintDevTreeModel> modelAll = new LinkedList<>();
        //设置树形主节点（不显示没有子集的）
        for (DictionaryDataEntity dicEntity : dicDataList) {
            PrintDevTreeModel model = new PrintDevTreeModel();
            model.setFullName(dicEntity.getFullName());
            model.setId(dicEntity.getId());
            Long num = printEntityList.stream().filter(t -> t.getCategory().equals(dicEntity.getId())).count();
            //编码底下存在的子节点总数
            if (num > 0) {
                model.setNum(Integer.parseInt(num.toString()));
                modelAll.add(model);
            }
        }
        List<String> userId = new ArrayList<>();
        printEntityList.forEach(t -> {
            userId.add(t.getCreatorUserId());
            if (StringUtil.isNotEmpty(t.getLastModifyUserId())) {
                userId.add(t.getLastModifyUserId());
            }
        });
        List<UserEntity> userList = userService.getUserName(userId);
        //设置子节点分支
        for (PrintDevEntity printEntity : printEntityList) {
            DictionaryDataEntity dicDataEntity = dicDataList.stream()
                    .filter(t -> t.getId().equals(printEntity.getCategory())).findFirst().orElse(null);
            //如果字典存在则装入容器
            PrintDevTreeModel model = JsonUtil.getJsonToBean(printEntity, PrintDevTreeModel.class);
            if (dicDataEntity != null) {
                //创建者
                UserEntity creatorUser = userList.stream().filter(t -> t.getId().equals(model.getCreatorUser())).findFirst().orElse(null);
                model.setCreatorUser(creatorUser != null ? creatorUser.getRealName() + "/" + creatorUser.getAccount() : "");
                //修改人
                UserEntity lastmodifyuser = userList.stream().filter(t -> t.getId().equals(model.getLastModifyUser())).findFirst().orElse(null);
                model.setLastModifyUser(lastmodifyuser != null ? lastmodifyuser.getRealName() + "/" + lastmodifyuser.getAccount() : "");

                model.setParentId(dicDataEntity.getId());
                modelAll.add(model);
            }
        }
        List<SumTree<PrintDevTreeModel>> trees = TreeDotUtils.convertListToTreeDot(modelAll);
        List<PrintDevVO> list = JsonUtil.getJsonToList(trees, PrintDevVO.class);
        return list;
    }

    @Override
    public void creUpdateCheck(PrintDevEntity printDevEntity, Boolean fullNameCheck, Boolean encodeCheck) {
        String fullName = printDevEntity.getFullName();
        String encode = printDevEntity.getEnCode();
        // 名称长度验证
        if (fullName.length() > 80) {
            throw new DataException(MsgCode.EXIST005.get());
        }
        QueryWrapper<PrintDevEntity> query = new QueryWrapper<>();
        //重名验证
        if (fullNameCheck) {
            query.lambda().eq(PrintDevEntity::getFullName, fullName);
            if (this.list(query).size() > 0) {
                throw new DataException(MsgCode.EXIST003.get());
            }
        }
        //编码验证
        if (encodeCheck) {
            query.clear();
            query.lambda().eq(PrintDevEntity::getEnCode, encode);
            if (this.list(query).size() > 0) {
                throw new DataException(MsgCode.EXIST002.get());
            }
        }
    }

    @Override
    public List<PrintOption> getPrintTemplateOptions(List<String> ids) {
        QueryWrapper<PrintDevEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(PrintDevEntity::getId, ids);
        List<PrintDevEntity> list = this.list(wrapper);
        List<PrintOption> options = JsonUtil.getJsonToList(list, PrintOption.class);
        return options;
    }


    @Override
    @Transactional
    public String importData(PrintDevInfoVO infoVO, Integer type) {
        PrintDevEntity entity = JsonUtil.getJsonToBean(infoVO, PrintDevEntity.class);
        StringJoiner stringJoiner = new StringJoiner("、");
        //id为空切名称不存在时
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PrintDevEntity::getId, entity.getId());
        if (this.getById(infoVO.getId()) != null) {
            if (Objects.equals(type, 0)) {
                stringJoiner.add("ID");
            } else {
                entity.setId(RandomUtil.uuId());
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PrintDevEntity::getEnCode, entity.getEnCode());
        if (this.count(queryWrapper) > 0) {
            stringJoiner.add(MsgCode.IMP009.get());
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PrintDevEntity::getFullName, entity.getFullName());
        if (this.count(queryWrapper) > 0) {
            stringJoiner.add(MsgCode.IMP008.get());
        }
        if (stringJoiner.length() > 0 && ObjectUtil.equal(type, 1)) {
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
        } else if (ObjectUtil.equal(type, 0) && stringJoiner.length() > 0) {
            return stringJoiner.toString() + MsgCode.IMP007.get();
        }
        entity.setState(0);
        entity.setCreatorTime(new Date());
        entity.setCreatorUserId(UserProvider.getLoginUserId());
        entity.setLastModifyTime(null);
        entity.setLastModifyUserId(null);
        this.setIgnoreLogicDelete().removeById(entity);
        this.setIgnoreLogicDelete().saveOrUpdate(entity);
        this.clearIgnoreLogicDelete();
        //版本添加
        PrintVersionEntity versionEntity = new PrintVersionEntity();
        String versionId = RandomUtil.uuId();
        versionEntity.setId(versionId);
        versionEntity.setTemplateId(entity.getId());
        versionEntity.setCreatorUserId(UserProvider.getUser().getUserId());
        versionEntity.setCreatorTime(new Date());
        versionEntity.setPrintTemplate(infoVO.getPrintTemplate());
        versionEntity.setConvertConfig(infoVO.getConvertConfig());
        versionEntity.setVersion(1);
        versionEntity.setState(0);
        versionEntity.setSortCode(0l);
        printVersionService.save(versionEntity);
        //数据集创建
        List<DataSetForm> dataSetList = infoVO.getDataSetList() != null ? JsonUtil.getJsonToList(infoVO.getDataSetList(), DataSetForm.class) : new ArrayList<>();
        dataSetList.stream().forEach(t -> t.setId(null));
        dataSetService.create(dataSetList, DataSetTypeEnum.PRINT_VER.getCode(), versionId);
        return "";
    }


    @Override
    public List<OperatorRecordEntity> getFlowTaskOperatorRecordList(String taskId) {
        List<OperatorRecordEntity> operatorRecordList = new ArrayList<>();
        if (StringUtil.isEmpty(taskId)) {
            return operatorRecordList;
        }
        try {
            // TODO 不同库之间的表名大小写问题
//            String sql = "SELECT * FROM workflow_record WHERE f_task_id = ? ORDER BY f_handle_time";
//            operatorRecordList = JdbcUtil.queryCustomMods(new PrepSqlDTO(sql, taskId).withConn(dataSourceUtil, null), OperatorRecordEntity.class);
            List<RecordEntity> recordList = taskApi.getRecordList(taskId);
            operatorRecordList = JsonUtil.getJsonToList(recordList, OperatorRecordEntity.class);
            //已办人员
            operatorRecordList.forEach(or -> {
//                or.setHandleTime(or.getHandleTimeOrigin().getTime());
                UserEntity userEntity = userService.getInfo(or.getHandleId());
                or.setUserName(userEntity != null ? userEntity.getRealName() + "/" + userEntity.getAccount() : "");
                or.setHandleStatus(or.getHandleType());
            });
        } catch (Exception e) {
            e.getMessage();
        }
        return operatorRecordList;
    }

    @Override
    public Map<String, Object> getDataMap(String templateId, String formId, String flwoTaskId, Map<String, Object> params) {
        List<PrintVersionEntity> versionList = printVersionService.getList(templateId);
        if (CollectionUtils.isEmpty(versionList)) {
            throw new DataException(MsgCode.PRI001.get());
        }
        //启用中的版本
        PrintVersionEntity startVersion = versionList.get(0);
        Map<String, Object> dataMap = new HashMap<>(16);
        dataMap.put("printTemplate", startVersion.getPrintTemplate());
        String convertConfig = startVersion.getConvertConfig();
        dataMap.put("convertConfig", startVersion.getConvertConfig());

        List<OperatorRecordEntity> operatorRecordList = this.getFlowTaskOperatorRecordList(flwoTaskId);
        dataMap.put("operatorRecordList", operatorRecordList);

        Map<String, Object> printData = new HashMap<>(16);
        List<DataSetEntity> list = dataSetService.getList(new DataSetPagination(DataSetTypeEnum.PRINT_VER.getCode(), startVersion.getId()));
        for (DataSetEntity item : list) {
            Map<String, Object> dataMapOrList = dataSetService.getDataMapOrList(item, params, formId, false);
            dataSetSwapUtil.swapData(templateId, convertConfig, dataMapOrList);
            printData.putAll(dataMapOrList);
        }
        dataMap.put("printData", printData);
        return dataMap;
    }

    @Override
    public void copyPrintdev(String templateId) {
        PrintDevEntity entity = this.getById(templateId);
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        String fullName = entity.getFullName() + ".副本" + copyNum;
        if (fullName.length() > 50) {
            throw new DataException(MsgCode.PRI006.get());
        }
        PrintDevFormDTO form = JsonUtil.getJsonToBean(entity, PrintDevFormDTO.class);
        form.setId(RandomUtil.uuId());
        form.setFullName(fullName);
        form.setEnCode(entity.getEnCode() + copyNum);

        List<PrintVersionEntity> list = printVersionService.getList(templateId);
        if (CollectionUtils.isNotEmpty(list)) {
            PrintVersionEntity versionEntity = list.get(0);
            form.setPrintTemplate(versionEntity.getPrintTemplate());
            form.setConvertConfig(versionEntity.getConvertConfig());
            List<DataSetEntity> dst = dataSetService.getList(new DataSetPagination(DataSetTypeEnum.PRINT_VER.getCode(), versionEntity.getId()));
            List<DataSetForm> dataSetFormList = new ArrayList<>();
            for (DataSetEntity item : dst) {
                DataSetForm dataSetForm = JsonUtil.getJsonToBean(item, DataSetForm.class);
                dataSetForm.setId(null);
                dataSetFormList.add(dataSetForm);
            }
            form.setDataSetList(dataSetFormList);
        }
        this.create(form);
    }

    @Override
    public List<PrintDevEntity> getWorkSelector(PaginationPrint pagination) {
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(pagination.getKeyword())) {
            queryWrapper.lambda().and(
                    t -> t.like(PrintDevEntity::getFullName, pagination.getKeyword())
                            .or().like(PrintDevEntity::getEnCode, pagination.getKeyword())
            );
        }
        if (StringUtil.isNotEmpty(pagination.getCategory())) {
            queryWrapper.lambda().eq(PrintDevEntity::getCategory, pagination.getCategory());
        }

        //是发布
        queryWrapper.lambda().eq(PrintDevEntity::getState, 1);
        //是通用
        queryWrapper.lambda().eq(PrintDevEntity::getCommonUse, 1);

        if (Objects.nonNull(pagination.getVisibleType())) {
            queryWrapper.lambda().eq(PrintDevEntity::getVisibleType, pagination.getVisibleType());
        } else {
            //权限判断
            if(authorizeService.getUserCurrentStanding(UserProvider.getUser().getUserId(),3)) {
                List<String> authList = new ArrayList<>();
                List<String> roleIdList = new ArrayList<>();
                permissionGroupService.getPermissionGroupByUserId(UserProvider.getLoginUserId(), null, true, null).forEach(t -> {
                    roleIdList.add(t.getId());
                });
                authList.addAll(authorizeService.getListByRoleIdsAndItemType(roleIdList, "print").stream().map(AuthorizeEntity::getItemId).collect(Collectors.toList()));
                queryWrapper.lambda().and(
                        t -> t.eq(PrintDevEntity::getVisibleType, 1).or().in(!authList.isEmpty(), PrintDevEntity::getId, authList)
                );
            }
        }

        queryWrapper.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        if (Objects.equals(pagination.getDataType(), 1)) {
            return this.list(queryWrapper);
        }
        Page<PrintDevEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<PrintDevEntity> iPage = this.page(page, queryWrapper);
        return pagination.setData(iPage.getRecords(), page.getTotal());
    }

    @Override
    public List<PrintDevEntity> getWorkSelector(List<String> id) {
        List<PrintDevEntity> list = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(id)){
            QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(PrintDevEntity::getId,id);
            queryWrapper.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
            list = this.list(queryWrapper);
        }
        return list;
    }

}

