package cn.yunzhixue.ability.center.examsprint.domain.report;

import java.time.Instant;

public record ExamSprintReport(
        String reportId,
        ReportType reportType,
        ReportContent content,
        ReportGenerationStatus generationStatus,
        Instant createdAt,
        Instant updatedAt,
        Instant expiresAt,
        String storageObjectKey,
        String fileName,
        String failureReason) {

    public ExamSprintReport {
        if (content != null && reportType != content.reportType()) {
            throw new IllegalArgumentException("reportType must match content.reportType");
        }
    }

    public static ExamSprintReport pending(
            String reportId,
            ReportType reportType,
            ReportContent content,
            Instant createdAt,
            Instant expiresAt) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.PENDING,
                createdAt,
                createdAt,
                expiresAt,
                null,
                null,
                null);
    }

    public ExamSprintReport processing(Instant updatedAt) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.PROCESSING,
                createdAt,
                updatedAt,
                expiresAt,
                storageObjectKey,
                fileName,
                null);
    }

    public ExamSprintReport success(Instant updatedAt, String storageObjectKey, String fileName) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.SUCCESS,
                createdAt,
                updatedAt,
                expiresAt,
                storageObjectKey,
                fileName,
                null);
    }

    public ExamSprintReport failed(Instant updatedAt, String failureReason) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.FAILED,
                createdAt,
                updatedAt,
                expiresAt,
                storageObjectKey,
                fileName,
                failureReason);
    }

    public ExamSprintReport expired(Instant updatedAt) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.EXPIRED,
                createdAt,
                updatedAt,
                expiresAt,
                storageObjectKey,
                fileName,
                failureReason);
    }

    public ExamSprintReport expiredWithStorageCleared(Instant updatedAt) {
        return new ExamSprintReport(
                reportId,
                reportType,
                content,
                ReportGenerationStatus.EXPIRED,
                createdAt,
                updatedAt,
                expiresAt,
                null,
                null,
                failureReason);
    }

    public boolean isExpiredAt(Instant instant) {
        return !expiresAt.isAfter(instant);
    }
}
