package com.hotwj.platform.securityManagement.trainingAudit.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.securityManagement.trainingAudit.domain.HotTrainingAudit;
import com.hotwj.platform.securityManagement.trainingAudit.domain.bo.HotTrainingAuditBatchBo;
import com.hotwj.platform.securityManagement.trainingAudit.domain.bo.HotTrainingAuditBo;
import com.hotwj.platform.securityManagement.trainingAudit.domain.vo.HotTrainingAuditVo;
import com.hotwj.platform.securityManagement.trainingAudit.mapper.HotTrainingAuditMapper;
import com.hotwj.platform.securityManagement.trainingAudit.service.IHotTrainingAuditService;
import com.hotwj.platform.securityManagement.trainingParticipant.domain.HotTrainingParticipant;
import com.hotwj.platform.securityManagement.trainingParticipant.mapper.HotTrainingParticipantMapper;
import com.hotwj.platform.securityManagement.trainingProgress.service.TrainingProgressService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 培训审核Service业务层处理
 *
 * @author shihongwei
 * @date 2025-12-29
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotTrainingAuditServiceImpl implements IHotTrainingAuditService {

    private final HotTrainingAuditMapper baseMapper;
    private final HotTrainingParticipantMapper trainingParticipantMapper;
    private final TrainingProgressService trainingProgressService;

    /**
     * 查询培训审核
     *
     * @param id 主键
     * @return 培训审核
     */
    @Override
    public HotTrainingAuditVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询培训审核列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 培训审核分页列表
     */
    @Override
    public TableDataInfo<HotTrainingAuditVo> queryPageList(HotTrainingAuditBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotTrainingAudit> lqw = buildQueryWrapper(bo);
        Page<HotTrainingAuditVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的培训审核列表
     *
     * @param bo 查询条件
     * @return 培训审核列表
     */
    @Override
    public List<HotTrainingAuditVo> queryList(HotTrainingAuditBo bo) {
        LambdaQueryWrapper<HotTrainingAudit> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HotTrainingAudit> buildQueryWrapper(HotTrainingAuditBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotTrainingAudit> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(HotTrainingAudit::getId);
        lqw.eq(bo.getCompanyId() != null, HotTrainingAudit::getCompanyId, bo.getCompanyId());
        lqw.eq(bo.getTrainingId() != null, HotTrainingAudit::getTrainingId, bo.getTrainingId());
        lqw.eq(bo.getUserId() != null, HotTrainingAudit::getUserId, bo.getUserId());
        lqw.eq(bo.getIsPass() != null, HotTrainingAudit::getIsPass, bo.getIsPass());
        lqw.eq(bo.getAuditorId() != null, HotTrainingAudit::getAuditorId, bo.getAuditorId());
        lqw.like(StringUtils.isNotBlank(bo.getAuditorName()), HotTrainingAudit::getAuditorName, bo.getAuditorName());
        lqw.eq(bo.getAuditTime() != null, HotTrainingAudit::getAuditTime, bo.getAuditTime());
        lqw.eq(StringUtils.isNotBlank(bo.getSignImgUrl()), HotTrainingAudit::getSignImgUrl, bo.getSignImgUrl());
        lqw.eq(bo.getIsDeleted() != null, HotTrainingAudit::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增培训审核
     *
     * @param bo 培训审核
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotTrainingAuditBo bo) {
        fillAuditInfo(bo);
        HotTrainingAudit add = MapstructUtils.convert(bo, HotTrainingAudit.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            syncParticipantPassStatus(bo);
        }
        return flag;
    }

    /**
     * 修改培训审核
     *
     * @param bo 培训审核
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotTrainingAuditBo bo) {
        fillAuditInfo(bo);
        HotTrainingAudit update = MapstructUtils.convert(bo, HotTrainingAudit.class);
        validEntityBeforeSave(update);
        boolean flag = baseMapper.updateById(update) > 0;
        if (flag) {
            syncParticipantPassStatus(bo);
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchAudit(HotTrainingAuditBatchBo bo) {
        if (bo.getCompanyId() == null || bo.getTrainingId() == null
                || StringUtils.isBlank(bo.getSignImgUrl())
                || bo.getAuditItems() == null || bo.getAuditItems().isEmpty()) {
            return false;
        }
        String auditorId = LoginHelper.getBusinessUserId();
        String auditorName = LoginHelper.getUsername();
        Date auditTime = new Date();
        int affected = 0;
        for (HotTrainingAuditBo item : bo.getAuditItems()) {
            if (item == null || StringUtils.isBlank(item.getUserId()) || item.getIsPass() == null) {
                continue;
            }
            String userId = item.getUserId().trim();
            if (StringUtils.isBlank(userId)) {
                continue;
            }
            LambdaQueryWrapper<HotTrainingParticipant> participantLqw = Wrappers.lambdaQuery();
            participantLqw.eq(HotTrainingParticipant::getCompanyId, bo.getCompanyId())
                    .eq(HotTrainingParticipant::getTrainingId, bo.getTrainingId())
                    .eq(HotTrainingParticipant::getUserId, userId)
                    .eq(HotTrainingParticipant::getIsDeleted, 0L)
                    .last("limit 1");
            HotTrainingParticipant participant = trainingParticipantMapper.selectOne(participantLqw);
            if (participant == null) {
                continue;
            }
            LambdaQueryWrapper<HotTrainingAudit> auditLqw = Wrappers.lambdaQuery();
            auditLqw.eq(HotTrainingAudit::getCompanyId, bo.getCompanyId())
                    .eq(HotTrainingAudit::getTrainingId, bo.getTrainingId())
                    .eq(HotTrainingAudit::getUserId, userId)
                    .eq(HotTrainingAudit::getIsDeleted, 0L)
                    .last("limit 1");
            HotTrainingAudit existing = baseMapper.selectOne(auditLqw);

            HotTrainingAuditBo auditBo = new HotTrainingAuditBo();
            if (existing != null) {
                auditBo.setId(existing.getId());
            }
            auditBo.setCompanyId(bo.getCompanyId());
            auditBo.setTrainingId(bo.getTrainingId());
            auditBo.setUserId(userId);
            auditBo.setIsPass(item.getIsPass());
            auditBo.setRemark(item.getRemark());
            auditBo.setSignImgUrl(bo.getSignImgUrl());
            auditBo.setAuditorId(auditorId);
            auditBo.setAuditorName(auditorName);
            auditBo.setAuditTime(auditTime);

            boolean ok = existing == null ? insertByBo(auditBo) : updateByBo(auditBo);
            if (ok) {
                affected++;
            }
        }
        return affected > 0;
    }

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

    private void fillAuditInfo(HotTrainingAuditBo bo) {
        String userId = LoginHelper.getBusinessUserId();
        String username = LoginHelper.getUsername();
        if (userId != null) {
            bo.setAuditorId(userId);
        }
        if (StringUtils.isNotBlank(username)) {
            bo.setAuditorName(username);
        }
        bo.setAuditTime(new Date());
    }

    private void syncParticipantPassStatus(HotTrainingAuditBo bo) {
        if (bo.getCompanyId() == null || bo.getTrainingId() == null || StringUtils.isBlank(bo.getUserId())) {
            return;
        }
        LambdaQueryWrapper<HotTrainingParticipant> lqw = new LambdaQueryWrapper<>();
        lqw.eq(HotTrainingParticipant::getCompanyId, bo.getCompanyId())
                .eq(HotTrainingParticipant::getTrainingId, bo.getTrainingId())
                .eq(HotTrainingParticipant::getUserId, bo.getUserId())
                .eq(HotTrainingParticipant::getIsDeleted, 0L);
        HotTrainingParticipant participant = trainingParticipantMapper.selectOne(lqw);
        if (participant == null) {
            return;
        }
        participant.setIsPass(bo.getIsPass());
        if (Long.valueOf(0L).equals(bo.getIsPass())) {
            participant.setIsCompleted(0L);
            participant.setCompleteTime(null);
        }
        trainingParticipantMapper.updateById(participant);
        trainingProgressService.syncProgress(bo.getCompanyId(), bo.getTrainingId(), bo.getUserId());
    }

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