using System.Globalization;
using Eis.Application.Candidate;

namespace Eis.Infrastructure.Candidate;

internal sealed partial class CandidateService
{
    public async Task<CandidateDocumentResult> GetAdmitCardAsync(
        string sessionToken,
        string registrationId,
        CancellationToken cancellationToken)
    {
        var context = await ResolveAsync(sessionToken, profileRoute: false, cancellationToken);
        if (context.Error is not null)
        {
            return DocumentError(context.Error);
        }

        var user = context.User!;
        var snapshot = await snapshotLoader.LoadAsync(user.Id, cancellationToken);
        var registration = snapshot.Registrations.FirstOrDefault(item => item.Id == registrationId);
        if (registration?.AdmitCard is null)
        {
            return DocumentError(Error(404, "准考证尚未生成"));
        }

        var exam = snapshot.Exams.First(item => item.Id == registration.ExamId);
        var now = DateTimeOffset.UtcNow;
        if (TryDate(exam.AdmitDownloadStart, out var start) && now < start)
        {
            return DocumentError(Error(403, "准考证下载尚未开放"));
        }

        if (TryDate(exam.AdmitDownloadEnd, out var end) && now > end)
        {
            return DocumentError(Error(403, "准考证下载时间已结束"));
        }

        var html = CandidateAdmitCardRenderer.Render(snapshot, user, context.Profile!, registration, exam);
        return new CandidateDocumentResult(
            200,
            html,
            $"{exam.Name}-{Text(context.Profile!, "name")}-准考证.html",
            null);
    }

    private static bool TryDate(string value, out DateTimeOffset parsed) =>
        DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out parsed);

    private static CandidateDocumentResult DocumentError(CandidateEndpointResult error) =>
        new(error.StatusCode, null, null, error.Body);
}
