package com.zt.plat.module.qms.common.data.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigUserSignatureDO;
import com.zt.plat.module.qms.business.config.service.ConfigUserSignatureService;
import com.zt.plat.module.qms.common.data.controller.vo.DataOpinionPageReqVO;
import com.zt.plat.module.qms.common.data.controller.vo.DataOpinionRespVO;
import com.zt.plat.module.qms.common.data.controller.vo.DataOpinionSaveReqVO;
import com.zt.plat.module.qms.common.data.dal.dataobject.DataCommonType;
import com.zt.plat.module.qms.enums.QmsBpmConstant;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceApplyDO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.zt.plat.module.qms.common.data.dal.dataobject.DataOpinionDO;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;

import com.zt.plat.module.qms.common.data.dal.mapper.DataOpinionMapper;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.DATA_OPINION_NOT_EXISTS;

/**
 * 审批意见 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class DataOpinionServiceImpl implements DataOpinionService {

    @Resource private DataOpinionMapper dataOpinionMapper;

    @Resource private ConfigUserSignatureService configUserSignatureService;

    /*
    * 作废意见。流程退回时触发
    * todo 考虑节点排序，退回时只作废退回节点之后的意见
    * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableOpinionsByBusId(Long busId) {
        UpdateWrapper<DataOpinionDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("busId", busId);
        updateWrapper.set("cancelFlag", "1");
        dataOpinionMapper.update(updateWrapper);
    }

    /*
    * 流程回调后创建意见*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOpinionByWfCallback(DataCommonType entity, String activityId, String activityName, JSONObject taskVariables) {
        String opinionContent = taskVariables.getString(QmsBpmConstant.TASK_VARIABLE_REASON);
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String userName = SecurityFrameworkUtils.getLoginUserNickname();

        Long userId = loginUser.getId();
        Long deptId = loginUser.getVisitDeptId();
        String deptName = loginUser.getVisitDeptName();
        ConfigUserSignatureDO configUserSignatureDO = configUserSignatureService.getByUserId(userId);
        DataOpinionDO opinion = new DataOpinionDO();
        opinion.setBusinessId(entity.getBusinessId());
        opinion.setFlowInstanceId(entity.getFlowInstanceId());
        opinion.setNodeKey(activityId);
        opinion.setNodeName(activityName);
        opinion.setOpinionUserId(userId);
        opinion.setOpinionUserName(userName);
        opinion.setOpinionDepartmentId(deptId);
        opinion.setOpinionDepartmentName(deptName);
        opinion.setOpinionTime(LocalDateTime.now());
        opinion.setOpinionContent(opinionContent);
        opinion.setSortNo(0);
        if(configUserSignatureDO != null)
            opinion.setOpinionSignatureId(configUserSignatureDO.getId());
        dataOpinionMapper.insert(opinion);
    }

    @Override
    public List<DataOpinionDO> getListByBusId(Long busId) {
        LambdaQueryWrapper<DataOpinionDO> query = new LambdaQueryWrapper<>();
        query.eq(DataOpinionDO::getBusinessId, busId);
        query.eq(DataOpinionDO::getCancelFlag, "0");
        return dataOpinionMapper.selectList(query);
    }


    @Override
    public List<DataOpinionDO> getListByFlowInsId(String flowInsId) {
        LambdaQueryWrapper<DataOpinionDO> query = new LambdaQueryWrapper<>();
        query.eq(DataOpinionDO::getFlowInstanceId, flowInsId);
        query.eq(DataOpinionDO::getCancelFlag, "0");
        return dataOpinionMapper.selectList(query);
    }

    @Override
    public JSONObject assembleOpinion(Long busId) {
        List<DataOpinionDO> opinionList = this.getListByBusId(busId);
        List<DataOpinionRespVO> opinionRespVOList = BeanUtils.toBean(opinionList, DataOpinionRespVO.class);
        List<Long> signatureIdList = opinionRespVOList.stream().map(DataOpinionRespVO::getOpinionSignatureId).distinct().toList();
        List<ConfigUserSignatureDO> signatureList = new ArrayList<>();
        if(!signatureIdList.isEmpty())
            signatureList = configUserSignatureService.getByIdList(signatureIdList);
        JSONObject opinion = new JSONObject();
        for(DataOpinionRespVO opinionRespVO : opinionRespVOList){
            for(ConfigUserSignatureDO signature : signatureList){
                if(signature.getId().equals(opinionRespVO.getOpinionSignatureId())){
                    opinionRespVO.setSignatureIdBase64(signature.getSignatureContent());
                }
            }
            if(opinionRespVO.getOpinionTime() != null){
                opinionRespVO.setOpinionTimeYYYYMMDD(DateUtil.format(opinionRespVO.getOpinionTime(), "yyyy-MM-dd"));
            }
            String nodeKey = opinionRespVO.getNodeKey();
            opinion.put(nodeKey, opinionRespVO);
        }
        return opinion;
    }

    @Override
    public DataOpinionRespVO createDataOpinion(DataOpinionSaveReqVO createReqVO) {
        // 插入
        DataOpinionDO dataOpinion = BeanUtils.toBean(createReqVO, DataOpinionDO.class);
        dataOpinionMapper.insert(dataOpinion);
        // 返回
        return BeanUtils.toBean(dataOpinion, DataOpinionRespVO.class);
    }

    @Override
    public void updateDataOpinion(DataOpinionSaveReqVO updateReqVO) {
        // 校验存在
        validateDataOpinionExists(updateReqVO.getId());
        // 更新
        DataOpinionDO updateObj = BeanUtils.toBean(updateReqVO, DataOpinionDO.class);
        dataOpinionMapper.updateById(updateObj);
    }

    @Override
    public void deleteDataOpinion(Long id) {
        // 校验存在
        validateDataOpinionExists(id);
        // 删除
        dataOpinionMapper.deleteById(id);
    }

    @Override
        public void deleteDataOpinionListByIds(List<Long> ids) {
        // 校验存在
        validateDataOpinionExists(ids);
        // 删除
        dataOpinionMapper.deleteByIds(ids);
        }

    private void validateDataOpinionExists(List<Long> ids) {
        List<DataOpinionDO> list = dataOpinionMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(DATA_OPINION_NOT_EXISTS);
        }
    }

    private void validateDataOpinionExists(Long id) {
        if (dataOpinionMapper.selectById(id) == null) {
            throw exception(DATA_OPINION_NOT_EXISTS);
        }
    }

    @Override
    public DataOpinionDO getDataOpinion(Long id) {
        return dataOpinionMapper.selectById(id);
    }

    @Override
    public PageResult<DataOpinionDO> getDataOpinionPage(DataOpinionPageReqVO pageReqVO) {
        return dataOpinionMapper.selectPage(pageReqVO);
    }

}