package com.zt.plat.module.base.service.tmpltp;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.framework.tenant.core.context.CompanyContextHolder;
import com.zt.plat.module.base.controller.admin.templtp.vo.*;
import com.zt.plat.module.base.dal.dataobject.tmpltp.*;
import com.zt.plat.module.base.dal.mysql.tmpltp.*;
import com.zt.plat.module.infra.api.file.FileApi;
import com.zt.plat.module.infra.api.file.dto.FileCreateReqDTO;
import com.zt.plat.module.infra.api.file.dto.FileRespDTO;
import com.zt.plat.module.system.api.dept.DeptApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.*;

/**
 * 模板实例与业务中间 Service 实现类
 *
 * @author 后台管理-1
 */
@Slf4j
@Service
@Validated
public class TmplInscBsnRelServiceImpl implements TmplInscBsnRelService {
    @Resource
    private DeptApi deptApi;
    @Resource
    private TmplInscBsnRelMapper tmplInscBsnRelMapper;
    @Resource
    private TemplateInstanceService templateInstanceService;
    @Resource
    private TmplInscDatBsnService tmplInscDatBsnService;
    @Resource
    private TmplInscItmBsnService tmplInscItmBsnService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TmplInscBsnRelRespVO createTmplInscBsnRel(TmplInscBsnRelSaveReqVO createReqVO) {
//        TemplateInstanceRespVO templateInstance = templateInstanceService.getTemplateInstance(createReqVO.getInscId());
//        if (templateInstance == null) {
//            throw exception(TEMPLATE_INSTANCE_NOT_EXISTS);
//        }
//        String type = "cntt";
//        if (templateInstance.getCntt().isEmpty() && templateInstance.getOrigCntt().isEmpty()) {
//            throw exception(TEMPLATE_INSTANCE_FILE_NOT_EXISTS);
//        }
//        if (templateInstance.getCntt().isEmpty()) {
//            type = "origCntt";
//        }
//        //下载文件并且上传文件
//        fileUpload(createReqVO, templateInstance, type);
        // 插入
        TmplInscBsnRelDO tmplInscBsnRel = BeanUtils.toBean(createReqVO, TmplInscBsnRelDO.class);
        tmplInscBsnRel.setRelativityId(createReqVO.getBsnId());
        //  tmplInscBsnRel.setBsnId(Long.valueOf(createReqVO.getUuid()));
        tmplInscBsnRelMapper.insertOrUpdate(tmplInscBsnRel);
        // 返回
        return BeanUtils.toBean(tmplInscBsnRel, TmplInscBsnRelRespVO.class);
    }



    @Override
    public void updateTmplInscBsnRel(TmplInscBsnRelSaveReqVO updateReqVO) {
        // 校验存在
        validateTmplInscBsnRelExists(updateReqVO.getId());
        // 更新
        TmplInscBsnRelDO updateObj = BeanUtils.toBean(updateReqVO, TmplInscBsnRelDO.class);
        if (updateReqVO.getBsnId()!=null){
            updateObj.setRelativityId(updateReqVO.getBsnId());
        }
        tmplInscBsnRelMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTmplInscBsnRel(Long id) {
        // 校验存在
        validateTmplInscBsnRelExists(id);
        // 删除
        tmplInscBsnRelMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTmplInscBsnRelListByIds(List<Long> ids) {
        // 校验存在
        validateTmplInscBsnRelExists(ids);
        //删除业务实例字段值
        deleteFldOrItmByIds(tmplInscBsnRelMapper.selectByIds(ids).stream().map(TmplInscBsnRelDO::getRelativityId).map(String::valueOf).toList(), tmplInscDatBsnService);
        //删除业务实例字段值
        deleteFldOrItmByIds(tmplInscBsnRelMapper.selectByIds(ids).stream().map(TmplInscBsnRelDO::getRelativityId).map(String::valueOf).toList(), tmplInscItmBsnService);
        tmplInscBsnRelMapper.deleteByIds(ids);
    }

    private void validateTmplInscBsnRelExists(List<Long> ids) {
        List<TmplInscBsnRelDO> list = tmplInscBsnRelMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(TMPL_INSC_BSN_REL_NOT_EXISTS);
        }
    }

    private void validateTmplInscBsnRelExists(Long id) {
        if (tmplInscBsnRelMapper.selectById(id) == null) {
            throw exception(TMPL_INSC_BSN_REL_NOT_EXISTS);
        }
    }

    @Override
    public TmplInscBsnRelRespVO getTmplInscBsnRel(Long id) {
        TmplInscBsnRelDO tmplInscBsnRelDO = tmplInscBsnRelMapper.selectById(id);
        TmplInscBsnRelRespVO tmplInscBsnRelRespVO = BeanUtils.toBean(tmplInscBsnRelDO, TmplInscBsnRelRespVO.class);
        if (tmplInscBsnRelRespVO != null){
            getTmplInscBsnRelDetails(tmplInscBsnRelRespVO);
        }

        return tmplInscBsnRelRespVO;
    }

    @Override
    public PageResult<TmplInscBsnRelDO> getTmplInscBsnRelPage(TmplInscBsnRelPageReqVO pageReqVO) {
        return tmplInscBsnRelMapper.selectPage(pageReqVO);
    }

    @Override
    public void getTmplInscBsnRelDetails(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        tmplInscBsnRelRespVO.setDeptIds(setDeptData(tmplInscBsnRelRespVO));//获取部门使用范围
//        tmplInscBsnRelRespVO.setInstanceItemRespVOS(setInstanceItemRespVOS(tmplInscBsnRelRespVO));//获取条款;
//        tmplInscBsnRelRespVO.setTemplateInstanceDataRespVOS(setTemplateInstanceDataRespVOS(tmplInscBsnRelRespVO)); // 实例字段
        //业务条款
        tmplInscBsnRelRespVO.setTmplInscItmBsnRespVOS(setTmplInscItmBsnRespVOS(tmplInscBsnRelRespVO));
        //业务字段
        tmplInscBsnRelRespVO.setTmplInscDatBsnRespVOS(setTmplInscDatBsnRespVOS(tmplInscBsnRelRespVO));
        if (!tmplInscBsnRelRespVO.getDeptIds().isEmpty()) {
            tmplInscBsnRelRespVO.setDeptRespVOS(deptApi.getDeptList(tmplInscBsnRelRespVO.getDeptIds().stream().map(Long::valueOf).toList()).getData()); // 部门详情
        }
//        TemplateInstanceRespVO templateInstance = SpringUtil.getBean(TemplateInstanceService.class).getTemplateInstance(tmplInscBsnRelRespVO.getInscId());
//        if (templateInstance != null) {
//            tmplInscBsnRelRespVO.setInscName(!templateInstance.getName().isEmpty() ? templateInstance.getName() : "分类未命名");
//        }
    }

    @Override
    public void updateCntt(Long bsnId, String params) {
        List<TmplInscBsnRelDO> tmplInscBsnRelDOS = tmplInscBsnRelMapper.selectList(new LambdaQueryWrapper<TmplInscBsnRelDO>()
                .eq(TmplInscBsnRelDO::getRelativityId, bsnId).orderByDesc(TmplInscBsnRelDO::getVer)
        );
        if (tmplInscBsnRelDOS.isEmpty()) {
            throw exception(TEMPLATE_INSTANCE_FILE_NOT_EXISTS);
        }
        TmplInscBsnRelDO tmplInscBsnRelDO = tmplInscBsnRelDOS.get(0);
        tmplInscBsnRelDO.setCntt(params);
        tmplInscBsnRelMapper.updateById(tmplInscBsnRelDO);
        log.info("更新业务实例cntt字段值成功");
    }


    //业务条款
    private List<TmplInscItmBsnRespVO> setTmplInscItmBsnRespVOS(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        List<TmplInscItmBsnRespVO> tmplInscItmBsnRespVOS = BeanUtils.toBean(SpringUtil.getBean(TmplInscItmBsnMapper.class).selectList(new LambdaQueryWrapper<TmplInscItmBsnDO>()
                .eq(TmplInscItmBsnDO::getBsnId, tmplInscBsnRelRespVO.getId())
        ), TmplInscItmBsnRespVO.class);
//        tmplInscItmBsnRespVOS.forEach(tmplInscItmBsnRespVO -> {
//            tmplInscBsnRelRespVO.getInstanceItemRespVOS().forEach(instanceItemRespVO -> {
//                if (tmplInscItmBsnRespVO.getInscItmId().equals(instanceItemRespVO.getId())) {
//                    tmplInscItmBsnRespVO.setItmName(instanceItemRespVO.getItmName());
//                }
//            });
//        });
        return tmplInscItmBsnRespVOS;
    }

    //业务字段
    private List<TmplInscDatBsnRespVO> setTmplInscDatBsnRespVOS(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        List<TmplInscDatBsnRespVO> tmplInscDatBsnRespVOS = BeanUtils.toBean(SpringUtil.getBean(TmplInscDatBsnMapper.class).selectList(new LambdaQueryWrapper<TmplInscDatBsnDO>().eq(TmplInscDatBsnDO::getBsnId, tmplInscBsnRelRespVO.getId())), TmplInscDatBsnRespVO.class);

//        tmplInscDatBsnRespVOS.forEach(tmplInscDatBsnRespVO -> tmplInscBsnRelRespVO.getTemplateInstanceDataRespVOS().forEach(templateInstanceDataRespVO -> {
//            if (templateInstanceDataRespVO.getId().toString().equals(tmplInscDatBsnRespVO.getInscFldId())) {
//                tmplInscDatBsnRespVO.setFldVal(templateInstanceDataRespVO.getFldKy());
//                tmplInscDatBsnRespVO.setFldKy(templateInstanceDataRespVO.getFldKy());
//            }
//        }));
        return tmplInscDatBsnRespVOS;
    }

    // 实例数据
    private List<TemplateInstanceDataRespVO> setTemplateInstanceDataRespVOS(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        return BeanUtils.toBean(SpringUtil.getBean(TemplateInstanceDataMapper.class).selectList(new LambdaQueryWrapper<TemplateInstanceDataDO>()
                .eq(TemplateInstanceDataDO::getInscId, tmplInscBsnRelRespVO.getInscId())
                .eq(TemplateInstanceDataDO::getCompanyId, CompanyContextHolder.getCompanyId())), TemplateInstanceDataRespVO.class);
    }

    // 条款
    private List<TemplateInstanceItemRespVO> setInstanceItemRespVOS(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        List<TemplateInstanceItemDO> templateInstanceItemDOS = SpringUtil.getBean(TemplateInstanceItemMapper.class).selectList(new LambdaQueryWrapper<TemplateInstanceItemDO>()
                .eq(TemplateInstanceItemDO::getInscId, tmplInscBsnRelRespVO.getInscId())
                .eq(TemplateInstanceItemDO::getCompanyId, CompanyContextHolder.getCompanyId()));
        List<TemplateInstanceItemRespVO> templateInstanceItemRespVOS = BeanUtils.toBean(templateInstanceItemDOS, TemplateInstanceItemRespVO.class);
        TmplItmMapper tmplItmMapper = SpringUtil.getBean(TmplItmMapper.class);
        List<String> ids = templateInstanceItemRespVOS.stream().map(TemplateInstanceItemRespVO::getItmId).toList();
        if (ids.isEmpty()) {
            return templateInstanceItemRespVOS;
        }
        List<TmplItmDO> tmplItmDOS = tmplItmMapper.selectByIds(ids);
        tmplItmDOS.forEach(tmplItmDO -> {
            templateInstanceItemRespVOS.forEach(templateInstanceItemRespVO -> {
                if (templateInstanceItemRespVO.getItmId().equals(tmplItmDO.getId())) {
                    templateInstanceItemRespVO.setItmName(tmplItmDO.getItmName());
                }
            });
        });
        return templateInstanceItemRespVOS;
    }

    private List<String> setDeptData(TmplInscBsnRelRespVO tmplInscBsnRelRespVO) {
        Long loginUserCompanyId = SecurityFrameworkUtils.getLoginUserCompanyId();
        return SpringUtil.getBean(DepartmentInstanceRelativityMapper.class).selectList(new LambdaQueryWrapper<DepartmentInstanceRelativityDO>()
                        .eq(DepartmentInstanceRelativityDO::getTemplateInstanceId, tmplInscBsnRelRespVO.getInscId())
                        .eq(DepartmentInstanceRelativityDO::getCompanyId, loginUserCompanyId)
                )
                .stream()
                .map(DepartmentInstanceRelativityDO::getCompanyDepartmentId)
                .toList();

    }

    private void fileUpload(TmplInscBsnRelSaveReqVO createReqVO, TemplateInstanceRespVO templateInstance, String type) {
        String id = "";
        FileRespDTO fileRespDTO = null;
        FileApi fileApi = SpringUtil.getBean(FileApi.class);
        if (Objects.equals(type, "cntt")) {
            id = JSONObject.parseObject(templateInstance.getCntt()).get("id").toString();
            CommonResult<FileRespDTO> file = fileApi.getFile(Long.valueOf(id));
            if (!file.isSuccess()) {
                throw exception(FILE_PULL_EER);
            }
            fileRespDTO = file.getData();
        } else if (Objects.equals(type, "origCntt")) {
            JSONArray jsonArray = JSONArray.parseArray(templateInstance.getOrigCntt());
            if (jsonArray != null && !jsonArray.isEmpty()) {
                JSONObject firstObj = jsonArray.getJSONObject(0);
                id = firstObj.getString("id");
                CommonResult<FileRespDTO> file = fileApi.getFile(Long.valueOf(id));
                if (!file.isSuccess()) {
                    throw exception(FILE_PULL_EER);
                }
                fileRespDTO = file.getData();
            }
        } else {
            throw exception(ILLEGAL_OPERATION_TYPE);
        }
        if (fileRespDTO == null) {
            throw exception(FILE_NOT_EXISTS);
        }
        FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO();
        fileCreateReqDTO.setName(fileRespDTO.getName())
                .setDirectory("模版合同")
                .setType(fileCreateReqDTO.getType())
                .setContent(fileRespDTO.getContent());
        log.info("==================下载文件成功，开始上传文件==================");
        CommonResult<FileRespDTO> fileWithReturn = fileApi.createFileWithReturn(fileCreateReqDTO);
        if (!fileWithReturn.isSuccess()) {
            throw exception(FILE_UPLOAD_EER);
        }
        log.info("=====================上传文件成功=============================");
        Map<String, Object> fileInfo = new HashMap<>();
        fileInfo.put("id", String.valueOf(fileRespDTO.getId()));
        fileInfo.put("name", fileRespDTO.getName());
        fileInfo.put("directory", fileRespDTO.getDirectory());
        createReqVO.setCntt(JSONObject.toJSONString(fileInfo));
        log.info("创建的文件信息【{}】", fileInfo);
    }

    private <T> void deleteFldOrItmByIds(List<String> ids, T t) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        if (t instanceof TmplInscDatBsnService) {
            ((TmplInscDatBsnService) t).deleteTmplInscDatBsnListByBsnIds(ids);
            log.info("删除业务实例字段值【{}】", ids);
        } else if (t instanceof TmplInscItmBsnService) {
            ((TmplInscItmBsnService) t).deleteTmplInscDatBsnListByBsnIds(ids);
            log.info("删除业务实例条款值【{}】", ids);
        }
    }

    @Override
    public Map<String, Object> valueInfo(String cttId, String inscId) {
//        // 1、通过实例和合同Id获取业务
//        TmplInscBsnRelDO tmplInscBsnRelDO = tmplInscBsnRelMapper.selectOne(
//                TmplInscBsnRelDO::getRelativityId, cttId,
//                TmplInscBsnRelDO::getInscId, inscId
//        );
//        if (tmplInscBsnRelDO == null) {
//            throw exception(TMPL_INSC_BSN_REL_NOT_EXISTS);
//        }
//
//        List<ValueInfo> valueInfoS = new ArrayList<>();
//        // 2、获取绑定的字段
//        List<TmplInscDatBsnRespVO> tmplInscDatBsnList = tmplInscDatBsnService
//                .getTmplInscDatBsnListByBsnId(String.valueOf(tmplInscBsnRelDO.getRelativityId()));
//
//
//        Optional.ofNullable(tmplInscDatBsnList)
//                .ifPresent(list -> list.forEach(tmplInscDatBsnRespVO -> {
//                    ValueInfo valueInfo = new ValueInfo(
//                            tmplInscDatBsnRespVO.getId(),
//                            tmplInscDatBsnRespVO.getFldKy(),
//                            tmplInscDatBsnRespVO.getFldVal(),
//                            "field",
//                            tmplInscDatBsnRespVO.getInscFldId()
//                    );
//                    valueInfoS.add(valueInfo);
//                }));
//
//        // 3、获取条款
//        List<TmplInscItmBsnRespVO> tmplInscItmBsnList = tmplInscItmBsnService.getTmplInscItmBsnList(String.valueOf(tmplInscBsnRelDO.getRelativityId()));
//        Optional.ofNullable(tmplInscItmBsnList)
//                .ifPresent(list -> list.forEach(tmplInscItmBsnRespVO -> {
//                    ValueInfo valueInfo = new ValueInfo(
//                            tmplInscItmBsnRespVO.getId(),
//                            tmplInscItmBsnRespVO.getItmName(),
//                            tmplInscItmBsnRespVO.getVal(),
//                            "item",
//                            tmplInscItmBsnRespVO.getItmId()
//                    );
//                    valueInfoS.add(valueInfo);
//                }));

       // return Map.of("data", valueInfoS, "id", tmplInscBsnRelDO.getId());
        return null;
    }

    @Override
    public TmplInscBsnRelRespVO bseInfo(String cttId, String inscId) {
        TmplInscBsnRelDO tmplInscBsnRelDO = tmplInscBsnRelMapper.selectOne(
                TmplInscBsnRelDO::getRelativityId, cttId,
                TmplInscBsnRelDO::getInscId, inscId
        );
        return BeanUtils.toBean(tmplInscBsnRelDO, TmplInscBsnRelRespVO.class);
    }

    @Override
    public  Map<String, Object>  bseInfoById(String id) {
        // 1、通过实例和合同Id获取业务
        TmplInscBsnRelDO tmplInscBsnRelDO = tmplInscBsnRelMapper.selectById( id);
        if (tmplInscBsnRelDO == null) {
            throw exception(TMPL_INSC_BSN_REL_NOT_EXISTS);
        }

        List<ValueInfo> valueInfoS = new ArrayList<>();
        // 2、获取绑定的字段
        List<TmplInscDatBsnRespVO> tmplInscDatBsnList = tmplInscDatBsnService
                .getTmplInscDatBsnListByBsnId(String.valueOf(tmplInscBsnRelDO.getRelativityId()));


//        Optional.ofNullable(tmplInscDatBsnList)
//                .ifPresent(list -> list.forEach(tmplInscDatBsnRespVO -> {
//                    ValueInfo valueInfo = new ValueInfo(
//                            tmplInscDatBsnRespVO.getId(),
//                            tmplInscDatBsnRespVO.getFldKy(),
//                            tmplInscDatBsnRespVO.getFldVal(),
//                            "field",
//                            tmplInscDatBsnRespVO.getInscFldId()
//                    );
//                    valueInfoS.add(valueInfo);
//                }));

        // 3、获取条款
        List<TmplInscItmBsnRespVO> tmplInscItmBsnList = tmplInscItmBsnService.getTmplInscItmBsnList(String.valueOf(tmplInscBsnRelDO.getRelativityId()));
//        Optional.ofNullable(tmplInscItmBsnList)
//                .ifPresent(list -> list.forEach(tmplInscItmBsnRespVO -> {
//                    ValueInfo valueInfo = new ValueInfo(
//                            tmplInscItmBsnRespVO.getId(),
//                            tmplInscItmBsnRespVO.getItmName(),
//                            tmplInscItmBsnRespVO.getVal(),
//                            "item",
//                            tmplInscItmBsnRespVO.getItmId()
//                    );
//                    valueInfoS.add(valueInfo);
//                }));

        return Map.of("data", valueInfoS, "id", tmplInscBsnRelDO.getId());
    }


    private record ValueInfo(
            String id,
            String label,
            String value,
            String type,
            String codeNumber
    ) {
    }

}
