package com.hotwj.platform.securityManagement.hiddenDanger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotwj.platform.flow.service.ISysFlowService;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.HotHiddenDanger;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.bo.HotHiddenDangerBo;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.bo.HotHiddenDangerReviewRecordBo;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.vo.HotHiddenDangerVo;
import com.hotwj.platform.securityManagement.hiddenDanger.mapper.HotHiddenDangerMapper;
import com.hotwj.platform.securityManagement.hiddenDanger.service.IHotHiddenDangerReviewRecordService;
import com.hotwj.platform.securityManagement.hiddenDanger.service.IHotHiddenDangerService;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.domain.HotHiddenDangerInspection;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.mapper.HotHiddenDangerInspectionMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 隐患治理Service业务层处理
 *
 * @author shihongwei
 * @date 2026-01-03
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotHiddenDangerServiceImpl implements IHotHiddenDangerService {

    private final HotHiddenDangerMapper baseMapper;
    private final HotHiddenDangerInspectionMapper dangerInspectionMapper;
    private final IHotHiddenDangerReviewRecordService reviewRecordService;
    private final ISysFlowService flowService;

    /**
     * 查询隐患治理
     *
     * @param id 主键
     * @return 隐患治理
     */
    @Override
    public HotHiddenDangerVo queryById(Long id) {
        HotHiddenDangerVo vo = baseMapper.selectVoById(id);
        if (vo != null && StringUtils.isNotBlank(vo.getInstanceId())) {
            try {
                String userId = String.valueOf(LoginHelper.getBusinessUserId());
                vo.setTaskId(flowService.getTaskId(vo.getInstanceId(), userId));
                List<String> approverIds = flowService.getApproverIdsByInstance(vo.getInstanceId());
                if (approverIds != null && !approverIds.isEmpty()) {
                    vo.setCurrentApproverId(Optional.of(approverIds).orElse(new ArrayList<>()).stream().findFirst().orElse(null));
                }
            } catch (Exception e) {
                // ignore
            }
        }
        return vo;
    }

    /**
     * 分页查询隐患治理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 隐患治理分页列表
     */
    @Override
    public TableDataInfo<HotHiddenDangerVo> queryPageList(HotHiddenDangerBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotHiddenDanger> lqw = buildQueryWrapper(bo);
        Page<HotHiddenDangerVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        String userId = null;
        try {
            userId = String.valueOf(LoginHelper.getBusinessUserId());
        } catch (Exception e) {
            // ignore
        }

        if (userId != null && result.getRecords() != null) {
            for (HotHiddenDangerVo vo : result.getRecords()) {
                if (StringUtils.isNotBlank(vo.getInstanceId())) {
                    vo.setTaskId(flowService.getTaskId(vo.getInstanceId(), userId));
                }
            }
        }

        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的隐患治理列表
     *
     * @param bo 查询条件
     * @return 隐患治理列表
     */
    @Override
    public List<HotHiddenDangerVo> queryList(HotHiddenDangerBo bo) {
        LambdaQueryWrapper<HotHiddenDanger> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HotHiddenDanger> buildQueryWrapper(HotHiddenDangerBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotHiddenDanger> lqw = Wrappers.lambdaQuery();
        Object beginTime = params == null ? null : params.get("beginTime");
        Object endTime = params == null ? null : params.get("endTime");
        boolean hasBeginTime = beginTime != null && StringUtils.isNotBlank(String.valueOf(beginTime)) && !"null".equalsIgnoreCase(String.valueOf(beginTime));
        boolean hasEndTime = endTime != null && StringUtils.isNotBlank(String.valueOf(endTime)) && !"null".equalsIgnoreCase(String.valueOf(endTime));
        if (hasBeginTime && hasEndTime) {
            lqw.between(HotHiddenDanger::getCheckTime, beginTime, endTime);
        } else if (hasBeginTime) {
            lqw.ge(HotHiddenDanger::getCheckTime, beginTime);
        } else if (hasEndTime) {
            lqw.le(HotHiddenDanger::getCheckTime, endTime);
        }
        lqw.orderByDesc(HotHiddenDanger::getCreateTime);
        lqw.eq(bo.getCompanyId() != null, HotHiddenDanger::getCompanyId, bo.getCompanyId());
        lqw.eq(StringUtils.isNotBlank(bo.getDangerNo()), HotHiddenDanger::getDangerNo, bo.getDangerNo());
        lqw.like(StringUtils.isNotBlank(bo.getDangerName()), HotHiddenDanger::getDangerName, bo.getDangerName());
        lqw.eq(bo.getSourceType() != null, HotHiddenDanger::getSourceType, bo.getSourceType());
        lqw.like(StringUtils.isNotBlank(bo.getSourceName()), HotHiddenDanger::getSourceName, bo.getSourceName());
        lqw.eq(StringUtils.isNotBlank(bo.getSourceId()), HotHiddenDanger::getSourceId, bo.getSourceId());
        lqw.eq(StringUtils.isNotBlank(bo.getDescription()), HotHiddenDanger::getDescription, bo.getDescription());
        lqw.eq(!hasBeginTime && !hasEndTime && bo.getCheckTime() != null, HotHiddenDanger::getCheckTime, bo.getCheckTime());
        lqw.like(StringUtils.isNotBlank(bo.getCheckerName()), HotHiddenDanger::getCheckerName, bo.getCheckerName());
        lqw.eq(StringUtils.isNotBlank(bo.getEvidenceUrls()), HotHiddenDanger::getEvidenceUrls, bo.getEvidenceUrls());
        lqw.like(StringUtils.isNotBlank(bo.getEvaluatorName()), HotHiddenDanger::getEvaluatorName, bo.getEvaluatorName());
        lqw.eq(bo.getEvalTime() != null, HotHiddenDanger::getEvalTime, bo.getEvalTime());
        lqw.eq(StringUtils.isNotBlank(bo.getRiskProject()), HotHiddenDanger::getRiskProject, bo.getRiskProject());
        lqw.eq(StringUtils.isNotBlank(bo.getRiskLevel()), HotHiddenDanger::getRiskLevel, bo.getRiskLevel());
        lqw.eq(StringUtils.isNotBlank(bo.getEvalProcess()), HotHiddenDanger::getEvalProcess, bo.getEvalProcess());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernRequire()), HotHiddenDanger::getGovernRequire, bo.getGovernRequire());
        lqw.like(StringUtils.isNotBlank(bo.getGovernPersonName()), HotHiddenDanger::getGovernPersonName, bo.getGovernPersonName());
        lqw.eq(bo.getGovernDeadline() != null, HotHiddenDanger::getGovernDeadline, bo.getGovernDeadline());
        lqw.eq(StringUtils.isNotBlank(bo.getFundSource()), HotHiddenDanger::getFundSource, bo.getFundSource());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernPlan()), HotHiddenDanger::getGovernPlan, bo.getGovernPlan());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernResult()), HotHiddenDanger::getGovernResult, bo.getGovernResult());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernAttachUrls()), HotHiddenDanger::getGovernAttachUrls, bo.getGovernAttachUrls());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernPhotoUrls()), HotHiddenDanger::getGovernPhotoUrls, bo.getGovernPhotoUrls());
        lqw.eq(StringUtils.isNotBlank(bo.getGovernPersonSignTime()), HotHiddenDanger::getGovernPersonSignTime, bo.getGovernPersonSignTime());
        lqw.like(StringUtils.isNotBlank(bo.getReviewerName()), HotHiddenDanger::getReviewerName, bo.getReviewerName());
        lqw.eq(bo.getReviewTime() != null, HotHiddenDanger::getReviewTime, bo.getReviewTime());
        lqw.eq(StringUtils.isNotBlank(bo.getReviewSignTime()), HotHiddenDanger::getReviewSignTime, bo.getReviewSignTime());
        lqw.eq(bo.getIsQualified() != null, HotHiddenDanger::getIsQualified, bo.getIsQualified());
        lqw.eq(StringUtils.isNotBlank(bo.getReviewConclusion()), HotHiddenDanger::getReviewConclusion, bo.getReviewConclusion());
        lqw.eq(bo.getStatus() != null, HotHiddenDanger::getStatus, bo.getStatus());
        lqw.eq(bo.getIsDeleted() != null, HotHiddenDanger::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增隐患治理
     *
     * @param bo 隐患治理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotHiddenDangerBo bo) {
        HotHiddenDanger add = MapstructUtils.convert(bo, HotHiddenDanger.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改隐患治理
     *
     * @param bo 隐患治理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotHiddenDangerBo bo) {
        HotHiddenDanger update = MapstructUtils.convert(bo, HotHiddenDanger.class);
        validEntityBeforeSave(update);

        // 如果复查不合格，新增复查记录
        if (bo.getIsQualified() != null && bo.getIsQualified() == 0) {
            HotHiddenDangerReviewRecordBo recordBo = new HotHiddenDangerReviewRecordBo();
            recordBo.setHiddenDangerId(bo.getId());
            recordBo.setReviewerId(bo.getReviewerId());
            recordBo.setReviewerName(bo.getReviewerName());
            recordBo.setReviewTime(bo.getReviewTime());
            recordBo.setReviewConclusion(bo.getReviewConclusion());
            recordBo.setIsQualified(bo.getIsQualified());
            recordBo.setReviewSign(bo.getReviewSign());
            reviewRecordService.insertByBo(recordBo);
        }

        return baseMapper.updateById(update) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(HotHiddenDangerBo bo) {
        // 1. 参数校验
        if (StringUtils.isBlank(bo.getTaskId())) {
            throw new ServiceException("流程任务ID不能为空");
        }
        if (bo.getId() == null) {
            throw new ServiceException("隐患ID不能为空");
        }
        HotHiddenDanger oldDanger = baseMapper.selectById(bo.getId());
        if (oldDanger == null) {
            throw new ServiceException("隐患信息不存在");
        }

        // 2. 准备更新数据
        HotHiddenDanger update = MapstructUtils.convert(bo, HotHiddenDanger.class);
        
        // 3. 根据当前状态处理流转逻辑
        boolean pass = true;
        String comment = "通过";
        Long currentStatus = oldDanger.getStatus();

        // 隐患排查来源处理
        HotHiddenDangerInspection inspection = null;
        if (oldDanger.getDataSource() != null && oldDanger.getDataSource() == 1L && StringUtils.isNotBlank(oldDanger.getSourceId())) {
            try {
                inspection = dangerInspectionMapper.selectById(Long.valueOf(oldDanger.getSourceId()));
            } catch (NumberFormatException e) {
                log.warn("Invalid sourceId: {}", oldDanger.getSourceId());
            }
        }

        if (currentStatus == 0L) {
            // 阶段：评估 -> 治理
            update.setStatus(1L);
            comment = StringUtils.isBlank(bo.getEvalProcess()) ? "评估通过" : "评估完成";
            updateInspectState(inspection, 7L); // 治理
        } else if (currentStatus == 1L) {
            // 阶段：治理 -> 复查
            update.setStatus(2L);
            comment = StringUtils.isBlank(bo.getGovernResult()) ? "治理提交" : "治理完成";
            updateInspectState(inspection, 8L); // 复查
        } else if (currentStatus == 2L) {
            // 阶段：复查 -> 完结 或 驳回治理
            if (bo.getIsQualified() == null) {
                throw new ServiceException("请选择复查结论");
            }
            
            pass = bo.getIsQualified() == 1L;
            comment = bo.getReviewConclusion();

            if (pass) {
                update.setStatus(3L); // 合格 -> 完结
                updateInspectState(inspection, 9L); // 完结
            } else {
                update.setStatus(1L); // 不合格 -> 回退到治理
                updateInspectState(inspection, 7L); // 治理
                // 记录复查历史
                saveReviewRecord(bo);
            }
        } else {
            // 容错处理：未知状态
            log.warn("Unknown hidden danger status: {}", currentStatus);
        }

        // 4. 更新业务数据
        baseMapper.updateById(update);

        // 5. 推动流程
        flowService.audit(
                bo.getTaskId(),
                pass,
                comment,
                LoginHelper.getBusinessUserId()
        );
    }

    private void updateInspectState(HotHiddenDangerInspection inspection, Long status) {
        if (inspection == null || status == null) {
            return;
        }

        inspection.setStatus(status);

        dangerInspectionMapper.updateById(inspection);
    }

    /**
     * 保存复查记录
     */
    private void saveReviewRecord(HotHiddenDangerBo bo) {
        HotHiddenDangerReviewRecordBo recordBo = new HotHiddenDangerReviewRecordBo();
        recordBo.setHiddenDangerId(bo.getId());
        recordBo.setReviewerId(bo.getReviewerId());
        recordBo.setReviewerName(bo.getReviewerName());
        recordBo.setReviewTime(bo.getReviewTime());
        recordBo.setReviewConclusion(bo.getReviewConclusion());
        recordBo.setIsQualified(bo.getIsQualified());
        recordBo.setReviewSign(bo.getReviewSign());
        reviewRecordService.insertByBo(recordBo);
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HotHiddenDanger entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除隐患治理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
