package org.raddatz.familienarchiv.timeline;

import io.swagger.v3.oas.annotations.media.Schema;
import org.raddatz.familienarchiv.document.DatePrecision;

import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

/**
 * Unified DTO for timeline entries — covers curated {@link TimelineEvent} rows, derived
 * life-events ({@link DerivedEventType}), and archive letters (Documents).
 *
 * <p><b>Edit-affordance contract (for issue #7):</b> {@code derived == true || eventId == null}
 * means no edit link should be rendered by the frontend.
 *
 * <p><b>Letter display fields:</b> {@code senderName} — {@code ""} means unknown/unlinked
 * correspondent; frontend renders {@code 'Unbekannt'} fallback. Only populated for
 * {@link Kind#LETTER} entries.
 *
 * <p><b>Type field:</b> {@code null} for {@link Kind#LETTER} entries; frontend must not render
 * an event-type badge for letters.
 *
 * <p><b>Root-tag fields ({@code rootTagId}/{@code rootTagName}/{@code rootTagColor}):</b> the
 * letter's primary root tag — the root ancestor of its alphabetically-first assigned tag (#835).
 * All three are {@code null} for non-{@link Kind#LETTER} entries and for letters with no tags;
 * {@code rootTagColor} is additionally {@code null} when the resolved root carries no color token.
 * They are deliberately NOT {@code @Schema(requiredMode = REQUIRED)} so the generated TypeScript
 * types stay optional.
 *
 * <p><b>Letter→event link ({@code linkedEventId}):</b> for a {@link Kind#LETTER} entry, the id of
 * the curated {@link TimelineEvent} whose {@code documents} set contains the letter's document, or
 * {@code null} when the letter is referenced by no curated event (#850). Computed on read from the
 * existing {@code timeline_event_documents} join — no new column. {@code null} for non-letter
 * entries. Deliberately NOT {@code @Schema(requiredMode = REQUIRED)} so the generated TypeScript
 * type stays optional.
 *
 * <p>Callers of {@code TimelineEventService.assembleDerivedEvents()} must independently enforce
 * {@code READ_ALL} authorization before invoking that method (see ADR-043).
 */
public record TimelineEntryDTO(
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) Kind kind,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) DatePrecision precision,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) boolean derived,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String senderName,
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String receiverName,
        LocalDate eventDate,
        LocalDate eventDateEnd,
        String title,
        EventType type,
        UUID eventId,
        UUID documentId,
        List<UUID> linkedPersonIds,
        DerivedEventType derivedType,
        UUID rootTagId,
        String rootTagName,
        String rootTagColor,
        UUID linkedEventId
) {
}
