/**
 * API DTO types — mirror the backend (DATA-1/DATA-2) contract.
 *
 * Code is English/camelCase (matching the DTOs); German is UI-only (de.ts).
 * Enums are string unions matching the C# member names verbatim (assumes
 * JsonStringEnumConverter on the backend — confirmed with DATA-2).
 */

/** Gerbil.Gender — C# enum { unknown, male, female }. */
export type Gender = 'unknown' | 'male' | 'female'
export const GENDERS: Gender[] = ['unknown', 'male', 'female']

/** Gerbil.Status — C# enum { Breeding, Pet, Deceased, GivenAway, ForSale }. STATUS-MODEL: Active→Breeding (gated on Pam feature/status-model). */
export type GerbilStatus = 'Breeding' | 'Pet' | 'Deceased' | 'GivenAway' | 'ForSale'
export const GERBIL_STATUSES: GerbilStatus[] = ['Breeding', 'Pet', 'ForSale', 'Deceased', 'GivenAway']
/** Statuses the user can pick freely in the form; Deceased+GivenAway are derived by the backend. */
export const SELECTABLE_STATUSES: GerbilStatus[] = ['Breeding', 'Pet', 'ForSale']

/** ISO date string "YYYY-MM-DD" (maps to C# DateOnly). */
export type DateOnlyString = string

export interface Gerbil {
  id: string
  name: string
  gender: Gender
  status: GerbilStatus
  dateOfBirth: DateOnlyString | null
  dateOfDeath: DateOnlyString | null
  causeOfDeath: string | null
  goHomeDate: DateOnlyString | null
  litterId: string | null
  enclosureId: string | null
  colorVarietyId: string | null
  originContactId: string | null
  receiverContactId: string | null
  /** SEARCH-1/2b: free-text Herkunft (Züchter) from the import; Gridify-filterable. */
  originBreeder?: string | null
  /**
   * SEARCH-1/2b: normalized name (lowercase, [\s._-] stripped) — filter-only,
   * not part of the returned payload; present here so it can be a Gridify field.
   */
  nameSearch?: string | null
  /** Compact GEN-1 genotype string, e.g. "Aa CC Dd EE GG Pp Spsp rere" (or "?"-wildcards). */
  genotype: string | null
  notes: string | null
  /**
   * FEAT-14: Charakterbogen. Selected trait KEYS (see de.character.traits).
   * Optional until FEAT-14a backend exposes the fields; treat absent as [].
   */
  characterTraits?: string[] | null
  characterNote?: string | null
  /**
   * Residency (Bestand): true = part of the own clan (Kleine Chaoten), false =
   * external/pedigree-only ancestor imported for the Stammbaum. Gridify-filterable
   * (`isResident==true`); the Tiere list defaults to resident-only. Absent = treat
   * as resident (backend default true).
   */
  isResident?: boolean
  /** FORM-FIELDS-1: true=gehörlos, false=hörend, null=unbekannt. */
  isDeaf?: boolean | null
  /** STAMMBAUM-AVATAR: URL des Profilfotos (erstes Foto nach sortOrder); null = kein Foto. API-relativ oder absolut. */
  profilePhotoUrl?: string | null
  spottingType?: string | null
  isCastrated?: boolean
  /**
   * NACHVERFOLGUNG: Datenherkunft des Import-Eintrags als JSON-String (vom
   * Python-Merge erzeugt; siehe {@link GerbilProvenance} für die geparste Form).
   * null = manuell angelegtes Tier / keine Importdaten.
   */
  provenance?: string | null
  /**
   * Reihenfolge des Jungtiers innerhalb seines Wurfs (aus der Wurfchronik, nach
   * Geburtsgewicht). null = unbekannt → alphabetischer Fallback.
   */
  birthOrder?: number | null
}

/**
 * NACHVERFOLGUNG: geparste Datenherkunft eines importierten Tiers (JSON aus
 * {@link Gerbil.provenance}). Beschreibt, WELCHE Quellinformationen den
 * Datenbankeintrag erzeugt haben.
 */
export interface GerbilProvenance {
  /** Alle Quelldateien (Stammbäume / Wurfchronik), die beigetragen haben. */
  sourceFiles: string[]
  /** Anzahl der Rohdatensätze, die zu diesem Tier zusammengeführt wurden. */
  mergedRecordCount: number
  /** Hat ein Wurfchronik-Treffer beigetragen? */
  fromWurfchronik: boolean
  /** Wie die Eltern abgeleitet wurden (z. B. "chart-position", "decision"). */
  parentMethod?: string
  /** Konfidenz der Eltern-Ableitung (z. B. "low" | "medium" | "high"). */
  parentConfidence?: string
  /** Menschlich lesbare Herkunftshinweise (deutsch). */
  notes: string[]
  /**
   * Chronologischer, dateibezogener Verlauf (deutsch): liest sich wie ein
   * Protokoll, WELCHE Quelldatei WELCHE Angabe beigetragen hat (z. B.
   * „Geburtsdatum (27.03.2022) aus ‚Stammbaum von X.xlsx'."). Primärinhalt des
   * Datenherkunft-Dialogs.
   */
  history: string[]
}

/**
 * NACHVERFOLGUNG: geparste Datenherkunft eines beliebigen importierten Eintrags
 * (Tier, Kontakt oder Wurf). {@link GerbilProvenance} ist die Tier-Spezialisierung
 * mit zusätzlichen Eltern-Feldern; Kontakte/Würfe nutzen dieselbe Grundform.
 */
export type EntityProvenance = GerbilProvenance

/** Payload for POST /gerbils. */
export interface CreateGerbil {
  name: string
  gender: Gender
  status?: GerbilStatus
  dateOfBirth?: DateOnlyString | null
  dateOfDeath?: DateOnlyString | null
  causeOfDeath?: string | null
  goHomeDate?: DateOnlyString | null
  litterId?: string | null
  enclosureId?: string | null
  colorVarietyId?: string | null
  originContactId?: string | null
  receiverContactId?: string | null
  originBreeder?: string | null
  genotype?: string | null
  notes?: string | null
  characterTraits?: string[] | null
  characterNote?: string | null
  isResident?: boolean
  isDeaf?: boolean | null
  spottingType?: string | null
  isCastrated?: boolean
}

/** Payload for PUT /gerbils/{id} (all optional / partial update). */
export type UpdateGerbil = Partial<CreateGerbil>

export interface ColorVariety {
  id: string
  name: string
  canonicalGenotype: string | null
  sortOrder: number
}

export interface Enclosure {
  id: string
  name: string
  notes: string | null
  /** Maße als Freitext, z. B. "120×50 cm". */
  size: string | null
  /** Empfohlene/maximale Tieranzahl. */
  capacity: number | null
  /** Datum der letzten Reinigung (ISO yyyy-MM-dd). */
  lastCleanedDate: string | null
  /** Reinigungsintervall in Tagen. */
  cleaningCycleDays: number | null
  /** Berechnet: lastCleanedDate + cleaningCycleDays (ISO yyyy-MM-dd). */
  nextCleaningDate: string | null
}

export interface Contact {
  id: string
  name: string
  email: string | null
  phone: string | null
  address: string | null
  notes: string | null
  isBreeder: boolean
  isReceiver: boolean
  /** Namens-Anhängsel dieser Zucht (für Tiere fremder Züchter). */
  nameSuffix: string | null
  /**
   * NACHVERFOLGUNG: Datenherkunft des Import-Eintrags als JSON-String (vom
   * Python-Merge erzeugt; siehe {@link EntityProvenance}). null = manuell angelegt.
   */
  provenance?: string | null
}

export interface Litter {
  id: string
  name: string
  /** Wurfdatum (birth date). */
  date: DateOnlyString
  /** Wurfstärke — total born count. */
  totalBorn: number | null
  /**
   * Abgabedatum (auto-suggested ~35 days after birth, editable).
   * Optional in the type so existing Litter constructors (e.g. pedigree test
   * factories) keep compiling; the API DTO always includes it (nullable).
   */
  expectedGoHomeDate?: DateOnlyString | null
  notes?: string | null
  fatherId: string | null
  motherId: string | null
  /** LITTER-MORTALITY: pups that died within the first 8 weeks. */
  deathsWithin8Weeks?: number | null
  /** Totgeburten (tot geboren) — aus der xlsx-Wurfchronik importiert. */
  stillborn?: number | null
  /**
   * WURFCHRONIK-FILTER: true = in der Wurfchronik (Wurf-Liste) sichtbar,
   * false = ausgeblendet (z. B. fremde/pedigree-only Würfe). Server-seitig
   * Gridify-filterbar (`showInChronicle==true`). Auf der Tier-Detailseite werden
   * versteckte Würfe trotzdem gezeigt. Absent = behandeln wie true (Backend-Default).
   */
  showInChronicle?: boolean
  /**
   * NACHVERFOLGUNG: Datenherkunft des Import-Eintrags als JSON-String (vom
   * Python-Merge erzeugt; siehe {@link EntityProvenance}). null = manuell angelegt.
   */
  provenance?: string | null
}

/** Payload for POST /litters. */
export interface CreateLitter {
  name: string
  date: DateOnlyString
  totalBorn?: number | null
  expectedGoHomeDate?: DateOnlyString | null
  notes?: string | null
  fatherId?: string | null
  motherId?: string | null
  deathsWithin8Weeks?: number | null
  stillborn?: number | null
  /** WURFCHRONIK-FILTER: false = aus der Wurfchronik ausblenden (Default true). */
  showInChronicle?: boolean
}

export type UpdateLitter = Partial<CreateLitter>

/**
 * GEPRÜFTE TIERE: Status einer „vollständig korrekt"-Markierung / eines Schutzes
 * relativ zum Rohimport. "unchanged" = Import stimmt mit dem geprüften Stand überein;
 * "drifted" = Import weicht ab (siehe importDiff); "missing" = das Tier existiert im
 * Import nicht mehr.
 */
export type VerifiedStatus = 'unchanged' | 'drifted' | 'missing'

/** Ein Feld-Unterschied zwischen geprüftem Stand (golden) und Rohimport. */
export interface SnapshotDiff {
  path: string
  goldenValue: string | null
  importValue: string | null
}

/** Override-/Prüfstatus eines Tiers (Backend: GET /verified-gerbils[/{id}]). */
export interface VerifiedGerbil {
  gerbilId: string
  entityName: string | null
  /** true = „vollständig korrekt" (zertifiziert + voller Freeze); false = „geschützt" (Bearbeitung, feldweise). */
  isVerified: boolean
  status: VerifiedStatus
  verifiedAt: string | null
  updatedAt: string
  note: string | null
  /** Eigene-Feld-Schlüssel, die gegen den Import eingefroren sind. */
  protectedFields: string[]
  /** Wo der Rohimport vom geprüften Stand abweicht (nur verifizierte Tiere). */
  importDiff: SnapshotDiff[]
}

/** Paged list envelope returned by Gridify list endpoints. */
export interface Paged<T> {
  items: T[]
  totalCount: number
  page: number
  pageSize: number
}
