package com.njcn.rdms.module.project.service.performance;

import com.njcn.rdms.framework.common.pojo.PageResult;
import com.njcn.rdms.framework.common.util.object.BeanUtils;
import com.njcn.rdms.module.project.constant.PerformanceExcelCellConstants;
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceScoreCellMappingRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceTemplatePageReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceTemplateRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceTemplateUploadReqVO;
import com.njcn.rdms.module.project.dal.dataobject.performance.PerformanceTemplateDO;
import com.njcn.rdms.module.project.dal.mysql.performance.PerformanceTemplateMapper;
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;

@Service
public class PerformanceTemplateServiceImpl implements PerformanceTemplateService {

    @Resource
    private PerformanceTemplateMapper performanceTemplateMapper;

    @Override
    public PerformanceTemplateRespVO getCurrentTemplate() {
        PerformanceTemplateDO template = performanceTemplateMapper.selectCurrent();
        if (template == null) {
            throw exception(ErrorCodeConstants.PERFORMANCE_TEMPLATE_CURRENT_NOT_EXISTS);
        }
        return toRespVO(template);
    }

    @Override
    public PageResult<PerformanceTemplateRespVO> getTemplatePage(PerformanceTemplatePageReqVO reqVO) {
        PageResult<PerformanceTemplateDO> pageResult = performanceTemplateMapper.selectPage(reqVO);
        return new PageResult<>(pageResult.getList().stream()
                .map(this::toRespVO)
                .toList(), pageResult.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long uploadTemplate(PerformanceTemplateUploadReqVO reqVO) {
        if (Boolean.TRUE.equals(reqVO.getActiveFlag())) {
            deactivateAllTemplates();
        }
        PerformanceTemplateDO template = new PerformanceTemplateDO();
        template.setTemplateName(reqVO.getTemplateName().trim());
        template.setFileId(reqVO.getFileId());
        template.setFileName(reqVO.getFileName().trim());
        template.setVersionNo(performanceTemplateMapper.selectMaxVersionNo() + 1);
        template.setActiveFlag(Boolean.TRUE.equals(reqVO.getActiveFlag()));
        template.setUploadUserId(SecurityFrameworkUtils.getLoginUserId());
        template.setUploadUserName(defaultText(SecurityFrameworkUtils.getLoginUserNickname()));
        template.setUploadTime(LocalDateTime.now());
        template.setRemark(normalizeNullableText(reqVO.getRemark()));
        performanceTemplateMapper.insert(template);
        return template.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void activateTemplate(Long id) {
        PerformanceTemplateDO template = validateTemplateExists(id);
        deactivateAllTemplates();
        PerformanceTemplateDO update = new PerformanceTemplateDO();
        update.setId(template.getId());
        update.setActiveFlag(true);
        performanceTemplateMapper.updateById(update);
    }

    private PerformanceTemplateDO validateTemplateExists(Long id) {
        PerformanceTemplateDO template = id == null ? null : performanceTemplateMapper.selectById(id);
        if (template == null) {
            throw exception(ErrorCodeConstants.PERFORMANCE_TEMPLATE_NOT_EXISTS);
        }
        return template;
    }

    private void deactivateAllTemplates() {
        PerformanceTemplateDO update = new PerformanceTemplateDO();
        update.setActiveFlag(false);
        performanceTemplateMapper.update(update, new LambdaQueryWrapperX<PerformanceTemplateDO>()
                .eq(PerformanceTemplateDO::getActiveFlag, true));
    }

    private PerformanceTemplateRespVO toRespVO(PerformanceTemplateDO template) {
        PerformanceTemplateRespVO respVO = BeanUtils.toBean(template, PerformanceTemplateRespVO.class);
        respVO.setScoreCellMapping(scoreCellMapping());
        return respVO;
    }

    private PerformanceScoreCellMappingRespVO scoreCellMapping() {
        PerformanceScoreCellMappingRespVO respVO = new PerformanceScoreCellMappingRespVO();
        respVO.setActualScoreTotalCell(PerformanceExcelCellConstants.ACTUAL_SCORE_TOTAL_CELL);
        respVO.setBaseScoreTotalCell(PerformanceExcelCellConstants.BASE_SCORE_TOTAL_CELL);
        respVO.setExtraScoreTotalCell(PerformanceExcelCellConstants.EXTRA_SCORE_TOTAL_CELL);
        respVO.setResultDescriptionCells(PerformanceExcelCellConstants.RESULT_DESCRIPTION_CELLS);
        respVO.setActualScoreCells(PerformanceExcelCellConstants.ACTUAL_SCORE_CELLS);
        respVO.setBaseScoreCells(PerformanceExcelCellConstants.BASE_SCORE_CELLS);
        respVO.setExtraScoreCells(PerformanceExcelCellConstants.EXTRA_SCORE_CELLS);
        return respVO;
    }

    private String normalizeNullableText(String value) {
        if (!StringUtils.hasText(value)) {
            return null;
        }
        return value.trim();
    }

    private String defaultText(String value) {
        return StringUtils.hasText(value) ? value.trim() : "";
    }
}
