package com.njcn.gather.aireport.reportapproval.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.aireport.reportapproval.handler.ReportApprovalHandler;
import com.njcn.gather.aireport.reportapproval.handler.ReportApprovalHandlerRegistry;
import com.njcn.gather.aireport.reportapproval.mapper.ReportApprovalMapper;
import com.njcn.gather.aireport.reportapproval.pojo.param.ReportApprovalParam;
import com.njcn.gather.aireport.reportapproval.pojo.vo.ReportApprovalLogVO;
import com.njcn.gather.aireport.reportapproval.pojo.vo.ReportApprovalPendingVO;
import com.njcn.gather.aireport.reportapproval.service.ReportApprovalService;
import com.njcn.web.factory.PageFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

@Service
public class ReportApprovalServiceImpl implements ReportApprovalService {

    private final ReportApprovalMapper reportApprovalMapper;
    private final ReportApprovalHandlerRegistry reportApprovalHandlerRegistry;

    public ReportApprovalServiceImpl(ReportApprovalMapper reportApprovalMapper,
                                     ReportApprovalHandlerRegistry reportApprovalHandlerRegistry) {
        this.reportApprovalMapper = reportApprovalMapper;
        this.reportApprovalHandlerRegistry = reportApprovalHandlerRegistry;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pass(ReportApprovalParam.AuditParam param) {
        return audit(param, true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reject(ReportApprovalParam.AuditParam param) {
        return audit(param, false);
    }

    @Override
    public Page<ReportApprovalPendingVO> pendingPage(ReportApprovalParam.PendingQueryParam param) {
        ReportApprovalParam.PendingQueryParam query = param == null ? new ReportApprovalParam.PendingQueryParam() : param;
        if (StrUtil.isNotBlank(query.getReportType())) {
            reportApprovalHandlerRegistry.requireHandler(query.getReportType());
        }
        long current = PageFactory.getPageNum(query);
        long size = PageFactory.getPageSize(query);
        long offset = Math.max(0L, (current - 1L) * size);
        long total = reportApprovalMapper.countPendingReports(query);
        List<ReportApprovalPendingVO> records = total <= 0
                ? Collections.<ReportApprovalPendingVO>emptyList()
                : reportApprovalMapper.selectPendingPage(offset, size, query);
        Page<ReportApprovalPendingVO> page = new Page<ReportApprovalPendingVO>(current, size, total);
        page.setRecords(records);
        return page;
    }

    @Override
    public Page<ReportApprovalLogVO> logPage(ReportApprovalParam.LogQueryParam param) {
        ReportApprovalParam.LogQueryParam query = param == null ? new ReportApprovalParam.LogQueryParam() : param;
        return reportApprovalMapper.selectLogPage(
                new Page<ReportApprovalLogVO>(PageFactory.getPageNum(query), PageFactory.getPageSize(query)), query);
    }

    private boolean audit(ReportApprovalParam.AuditParam param, boolean passed) {
        if (param == null || StrUtil.isBlank(param.getReportType()) || StrUtil.isBlank(param.getReportId())) {
            throw new BusinessException(CommonResponseEnum.FAIL, "审批参数不能为空");
        }
        ReportApprovalHandler handler = reportApprovalHandlerRegistry.requireHandler(param.getReportType());
        return handler.audit(param, passed);
    }
}
