package com.njcn.gather.aireport.reportapproval.handler;

import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.aireport.reportapproval.component.ReportApprovalUserNameResolver;
import com.njcn.gather.aireport.reportapproval.mapper.ReportApprovalMapper;
import com.njcn.gather.aireport.reportapproval.pojo.constant.ReportApprovalConst;
import com.njcn.gather.aireport.reportapproval.pojo.param.ReportApprovalParam;
import com.njcn.gather.aireport.reportapproval.pojo.po.ReportApprovalLogPO;
import com.njcn.web.utils.RequestUtil;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;

public abstract class AbstractReportApprovalHandler implements ReportApprovalHandler {

    private final ReportApprovalMapper reportApprovalMapper;
    private final ReportApprovalUserNameResolver reportApprovalUserNameResolver;

    protected AbstractReportApprovalHandler(ReportApprovalMapper reportApprovalMapper,
                                            ReportApprovalUserNameResolver reportApprovalUserNameResolver) {
        this.reportApprovalMapper = reportApprovalMapper;
        this.reportApprovalUserNameResolver = reportApprovalUserNameResolver;
    }

    @Override
    public boolean audit(ReportApprovalParam.AuditParam param, boolean passed) {
        if (param == null || StrUtil.isBlank(param.getReportId())) {
            throw new BusinessException(CommonResponseEnum.FAIL, "审批参数不能为空");
        }
        String reason = trimToNull(param.getApprovalReason());
        if (reason == null) {
            throw new BusinessException(CommonResponseEnum.FAIL, "审批原因不能为空");
        }
        return doAudit(param.getReportId(), reason, passed);
    }

    protected abstract boolean doAudit(String reportId, String reason, boolean passed);

    protected void saveLog(String reportId, String reportName, String beforeState, String afterState,
                           String reason, String approverId, LocalDateTime approvalTime) {
        ReportApprovalLogPO log = new ReportApprovalLogPO();
        log.setId(UUID.randomUUID().toString());
        log.setReportType(getReportType());
        log.setReportId(reportId);
        log.setReportName(reportName);
        log.setApprovalResult(afterState);
        log.setApprovalReason(reason);
        log.setBeforeState(beforeState);
        log.setAfterState(afterState);
        log.setApproverId(approverId);
        log.setApproverName(resolveUserName(approverId));
        log.setApprovalTime(approvalTime);
        log.setStatus(ReportApprovalConst.STATUS_NORMAL);
        log.setCreateBy(approverId);
        log.setCreateTime(approvalTime);
        log.setUpdateBy(approverId);
        log.setUpdateTime(approvalTime);
        reportApprovalMapper.insert(log);
    }

    protected String resolveCurrentUserId() {
        String userId = RequestUtil.getUserId();
        return StrUtil.isBlank(userId) ? null : userId;
    }

    private String resolveUserName(String userId) {
        if (StrUtil.isBlank(userId)) {
            return null;
        }
        Map<String, String> userNameMap = reportApprovalUserNameResolver.resolveUserNames(Arrays.asList(userId));
        return userNameMap.containsKey(userId) ? userNameMap.get(userId) : userId;
    }

    private String trimToNull(String value) {
        if (value == null) {
            return null;
        }
        String text = value.trim();
        return text.isEmpty() ? null : text;
    }
}
