package com.hotwj.platform.reportStatistics.service.impl;

import com.hotwj.platform.driverManagement.driver.domain.vo.HotDriverVo;
import com.hotwj.platform.driverManagement.driver.service.IHotDriverService;
import com.hotwj.platform.reportStatistics.service.IDriverFilePrintService;
import com.hotwj.platform.reportStatistics.service.IReportDataProvider;
import com.hotwj.platform.reportStatistics.service.ReportPrintJob;
import com.hotwj.platform.reportStatistics.service.ReportRenderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 驾驶员档案打印 Service业务层处理
 *
 * @author shihongwei
 * @date 2026-01-04
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DriverFilePrintServiceImpl implements IDriverFilePrintService, InitializingBean {

    private final IHotDriverService driverService;
    private final ReportRenderService reportRenderService;
    private final List<IReportDataProvider> allProviders;

    private Map<String, IReportDataProvider> providerMap;

    @Override
    public void afterPropertiesSet() {
        // 初始化 Provider Map
        providerMap = allProviders.stream()
                .collect(Collectors.toMap(IReportDataProvider::getReportType, p -> p));
        // 手动添加映射，以防 Provider 的 simpleName 不匹配 TYPE 常量
        // 如果 Provider 类名和常量一致则无需手动，这里为了保险起见可以显式映射
        // 例如：TYPE_APPLICATION_FORM -> DriverApplicationFormProvider
    }

    @Override
    public byte[] generateApplicationForm(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_APPLICATION_FORM, driverIds, true);
    }

    @Override
    public byte[] generateIdCardScan(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_ID_CARD_SCAN, driverIds, true);
    }

    @Override
    public byte[] generateDriverLicenseCopy(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_DRIVER_LICENSE_COPY, driverIds, true);
    }

    @Override
    public byte[] generateQualificationCertificateCopy(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_QUALIFICATION_CERTIFICATE_COPY, driverIds, true);
    }

    @Override
    public byte[] generateQualificationReview(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_QUALIFICATION_REVIEW, driverIds, true);
    }

    @Override
    public byte[] generateAccidentRecord(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_ACCIDENT_RECORD, driverIds, true);
    }

    @Override
    public byte[] generateViolationRecord(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_VIOLATION_RECORD, driverIds, true);
    }

    @Override
    public byte[] generateAnnualAssessmentRecord(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_ANNUAL_ASSESSMENT_RECORD, driverIds, true);
    }

    @Override
    public byte[] generateMedicalExaminationReport(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_MEDICAL_EXAMINATION_REPORT, driverIds, true);
    }

    @Override
    public byte[] generateRewardPunishmentRecord(List<String> driverIds) throws Exception {
        return renderSingleProviderJob(IDriverFilePrintService.TYPE_REWARD_PUNISHMENT_RECORD, driverIds, true);
    }

    @Override
    public byte[] generateOneClickPrintPdf(List<String> driverIds, List<String> types) throws Exception {
        Long companyId = resolveCompanyId(driverIds);
        ReportPrintJob job = reportRenderService.createJob(this::getProviderByType)
                .withCompanyId(companyId)
                .useSeal(true);

        if (driverIds == null || types == null || driverIds.isEmpty() || types.isEmpty()) {
            return job.render();
        }

        // 先把有效 provider 解析出来，避免在双层循环中重复查 Map
        List<IReportDataProvider> providers = types.stream()
                .map(this::getProviderByType)
                .filter(java.util.Objects::nonNull)
                .toList();

        if (providers.isEmpty()) {
            return job.render();
        }

        // 性能优化：这里只需要 driverId 作为参数，不再逐个查询驾驶员详情
        for (String id : driverIds) {
            if (id == null) {
                continue;
            }
            for (IReportDataProvider provider : providers) {
                job.add(provider, Map.of("driverId", id));
            }
        }
        return job.render();
    }

    private byte[] renderSingleProviderJob(String type, List<String> driverIds, boolean useSeal) throws Exception {
        Long companyId = resolveCompanyId(driverIds);
        IReportDataProvider provider = getProviderByType(type);
        if (provider == null) {
            throw new IllegalArgumentException("未找到报表类型对应的 Provider: " + type);
        }
        ReportPrintJob job = reportRenderService.createJob(this::getProviderByType)
                .withCompanyId(companyId)
                .useSeal(useSeal)
                .addCover(provider, driverIds == null || driverIds.isEmpty() ? null : Map.of("driverId", driverIds.get(0)));
        return job.addBatch(provider, driverIds, "driverId").render();
    }

    private IReportDataProvider getProviderByType(String type) {
        return providerMap.get(type);
    }

    private Long resolveCompanyId(List<String> driverIds) {
        if (driverIds == null || driverIds.isEmpty()) {
            return null;
        }
        String firstId = driverIds.get(0);
        HotDriverVo driver = driverService.queryById(firstId);
        if (driver == null) {
            return null;
        }
        return driver.getCompanyId();
    }
}
