using Health.Domain.Entities;
using Health.Domain.Enums;

namespace Health.Application.Reports;

public sealed record ReportUploadFile(
    string FileName,
    long Length,
    Stream Content);

public sealed record ReportDto(
    Guid Id,
    Guid UserId,
    string FileUrl,
    string FileType,
    string Category,
    string Status,
    string AiStatus,
    string ReviewStatus,
    string? Severity,
    string? AiSummary,
    string? AiIndicators,
    string? DoctorComment,
    string? DoctorRecommendation,
    string? DoctorName,
    DateTime? ReviewedAt,
    DateTime CreatedAt);

public sealed record ReportUploadResult(
    bool Success,
    int Code,
    string? Message,
    ReportDto? Report);

public sealed record ReportAnalysisJob(
    Guid TaskId,
    Guid ReportId,
    string FilePath);

public sealed record StoredReportFile(
    string FileUrl,
    string FilePath);

public interface IReportService
{
    Task<IReadOnlyList<ReportDto>> GetReportsAsync(Guid userId, CancellationToken ct);
    Task<ReportDto?> GetReportAsync(Guid userId, Guid reportId, CancellationToken ct);
    Task<ReportUploadResult> UploadReportAsync(Guid userId, ReportUploadFile file, CancellationToken ct);
    Task<bool> DeleteReportAsync(Guid userId, Guid reportId, CancellationToken ct);
    Task<bool> ReanalyzeReportAsync(Guid userId, Guid reportId, CancellationToken ct);
}

public interface IReportAnalysisQueue
{
    Task EnqueueAsync(ReportAnalysisJob job, CancellationToken ct = default);
    Task RecoverStaleAsync(CancellationToken ct);
    Task<ReportAnalysisJob?> TryTakeAsync(CancellationToken ct);
    Task CompleteAsync(Guid taskId, CancellationToken ct);
    Task RetryAsync(Guid taskId, string error, CancellationToken ct);
}

public interface IReportAnalysisService
{
    Task AnalyzeAsync(ReportAnalysisJob job, CancellationToken ct);
}

public interface IReportRepository
{
    Task<IReadOnlyList<Report>> ListAsync(Guid userId, CancellationToken ct);
    Task<Report?> GetOwnedAsync(Guid userId, Guid reportId, CancellationToken ct);
    Task<Report?> GetByIdAsync(Guid reportId, CancellationToken ct);
    Task AddAsync(Report report, CancellationToken ct);
    void Delete(Report report);
    Task SaveChangesAsync(CancellationToken ct);
}

public interface IReportFileStorage
{
    Task<StoredReportFile> SaveAsync(ReportUploadFile file, string extension, CancellationToken ct);
    string GetLocalFilePath(string fileUrl);
    bool Exists(string filePath);
    void Delete(string filePath);
}
