namespace BigRegister.Api.Contracts;

// Wire contracts (the FE⇄BE seam). Field names + shapes mirror the frontend's
// contracts/*.dto.ts 1:1; the NSwag-generated TS client is produced from these.

public sealed record AdresDto(string Straat, string Postcode, string Woonplaats);

public sealed record RegistrationStatusDto(
    string Tag,
    string? HerregistratieDatum = null,
    string? GeschorstTot = null,
    string? Reden = null,
    string? DoorgehaaldOp = null);

public sealed record RegistrationDto(
    string BigNummer,
    string Naam,
    string Beroep,
    string Registratiedatum,
    string Geboortedatum,
    RegistrationStatusDto Status);

public sealed record PersonDto(string Naam, string Geboortedatum, AdresDto Adres);

public sealed record HerregistratieDecisionsDto(bool EligibleForHerregistratie, string? HerregistratieReason);

public sealed record DashboardViewDto(RegistrationDto Registration, PersonDto Person, HerregistratieDecisionsDto Decisions);

public sealed record AantekeningDto(string Type, string Omschrijving, string Datum);

public sealed record BrpAddressDto(bool Gevonden, AdresDto? Adres);

public sealed record PolicyQuestionDto(string Id, string Vraag, string Type);

public sealed record DuoDiplomaDto(
    string Id,
    string Naam,
    string Instelling,
    int Jaar,
    string Beroep,
    IReadOnlyList<PolicyQuestionDto> PolicyQuestions);

public sealed record ManualDiplomaPolicyDto(IReadOnlyList<string> Beroepen, IReadOnlyList<PolicyQuestionDto> PolicyQuestions);

public sealed record DuoLookupDto(IReadOnlyList<DuoDiplomaDto> Diplomas, ManualDiplomaPolicyDto Handmatig);

public sealed record IntakePolicyDto(int ScholingThreshold);

// --- Document upload contracts ---

public sealed record DocumentCategoryDto(
    string CategoryId, string Label, string Description, bool Required,
    IReadOnlyList<string> AcceptedTypes, int MaxSizeMb, bool Multiple, bool AllowPostDelivery);

public sealed record UploadCategoriesDto(IReadOnlyList<DocumentCategoryDto> Categories);

public sealed record UploadResponse(string DocumentId, string LocalId);

public sealed record UploadStatusItemDto(string LocalId, string Status, string? DocumentId);
public sealed record UploadStatusDto(IReadOnlyList<UploadStatusItemDto> Results);

// Per-category delivery intent on submit: digital categories carry their DocumentId,
// post-delivery categories carry Channel="post".
public sealed record DocumentRefDto(string CategoryId, string Channel, string? DocumentId = null);

// Submit requests carry only the fields the server re-validates (UX-only fields
// stay on the client). ponytail: a real submit would carry the full application.
public sealed record RegistratieRequest(string DiplomaHerkomst, IReadOnlyList<DocumentRefDto>? Documents = null);
public sealed record IntakeRequest(int Uren);
public sealed record HerregistratieRequest(int Uren, IReadOnlyList<DocumentRefDto>? Documents = null);
public sealed record ChangeRequestRequest(string Straat, string Postcode, string Woonplaats);

public sealed record ReferentieResponse(string Referentie);

// --- Applications (aanvragen): the system of record for the dashboard. ---

// Status is a discriminated union by Tag (Concept | InBehandeling | Goedgekeurd |
// Afgewezen); only the fields relevant to a tag are populated. Mirrors the FE union.
public sealed record AanvraagStatusDto(
    string Tag,
    int? StepIndex = null,
    int? StepCount = null,
    string? Referentie = null,
    bool? Manual = null,
    string? Reden = null);

public sealed record ApplicationSummaryDto(
    string Id, string Type, AanvraagStatusDto Status,
    IReadOnlyList<string> DocumentIds,
    string CreatedAt, string UpdatedAt, string? SubmittedAt);

public sealed record ApplicationDetailDto(
    string Id, string Type, AanvraagStatusDto Status,
    System.Text.Json.JsonElement? Draft,
    IReadOnlyList<string> DocumentIds,
    string CreatedAt, string UpdatedAt, string? SubmittedAt);

public sealed record CreateApplicationRequest(string Type);

public sealed record DraftSyncRequest(
    System.Text.Json.JsonElement Draft, int StepIndex, int StepCount,
    IReadOnlyList<string>? DocumentIds = null);

// Submit carries only the fields the server re-validates per wizard type.
public sealed record SubmitApplicationRequest(
    string? DiplomaHerkomst = null, int? Uren = null,
    IReadOnlyList<DocumentRefDto>? Documents = null);

public sealed record SubmitApplicationResponse(string Referentie, AanvraagStatusDto Status);

// --- Brief (letter composition) contracts ---
// Rich text is a serialisable node tree; the node union is flattened with a `Type`
// discriminator + nullable fields, the same wire convention as AanvraagStatusDto.
// The backend treats the content as opaque (stores/returns it) — the FE owns the
// rich-text semantics and re-validates at its parse* boundary.

public sealed record RichTextNodeDto(string Type, string? Text = null, IReadOnlyList<string>? Marks = null, string? Key = null);
// List is null for a plain paragraph, "bullet" or "number" for a list item.
public sealed record ParagraphDto(IReadOnlyList<RichTextNodeDto> Nodes, string? List = null);
public sealed record RichTextBlockDto(IReadOnlyList<ParagraphDto> Paragraphs);

public sealed record PlaceholderDefDto(string Key, string Label, bool AutoResolvable, bool? Fillable = null, bool? Deprecated = null);

// LetterBlock union (passage | freeText), flattened: passage-only fields are nullable.
public sealed record LetterBlockDto(
    string Type, string BlockId, RichTextBlockDto Content,
    string? SourcePassageId = null, int? SourceVersion = null, bool? Edited = null);

// Locked sections (aanhef, slot) are predefined template text the drafter cannot edit.
public sealed record LetterSectionDto(string SectionKey, string Title, bool Required, IReadOnlyList<LetterBlockDto> Blocks, bool Locked = false);

// BriefStatus union, flattened by Tag (draft | submitted | approved | rejected | sent).
public sealed record BriefStatusDto(
    string Tag,
    string? SubmittedBy = null, string? SubmittedAt = null,
    string? ApprovedBy = null, string? ApprovedAt = null,
    string? RejectedBy = null, string? RejectedAt = null, string? Comments = null,
    string? SentAt = null);

public sealed record LibraryPassageDto(
    string PassageId, string Scope, string SectionKey, string Label,
    RichTextBlockDto Content, int Version, string? Beroep = null);

public sealed record BriefDto(
    string BriefId, string Beroep, string TemplateId,
    IReadOnlyList<PlaceholderDefDto> Placeholders,
    IReadOnlyList<LetterSectionDto> Sections,
    BriefStatusDto Status, string DrafterId);

public sealed record BriefViewDto(BriefDto Brief, IReadOnlyList<LibraryPassageDto> AvailablePassages);

public sealed record SaveBriefRequest(IReadOnlyList<LetterSectionDto> Sections);
public sealed record RejectBriefRequest(string Comments);
