import { z } from 'zod';

// ---------------------------------------------------------------------------
// ENUMS (as const arrays for runtime use + TypeScript types)
// ---------------------------------------------------------------------------

export const EINSATZ_ARTEN = [
  'Brand',
  'THL',
  'ABC',
  'BMA',
  'Hilfeleistung',
  'Fehlalarm',
  'Brandsicherheitswache',
] as const;

export type EinsatzArt = (typeof EINSATZ_ARTEN)[number];

export const EINSATZ_ART_LABELS: Record<EinsatzArt, string> = {
  Brand: 'Brand',
  THL: 'Technische Hilfeleistung',
  ABC: 'ABC-Einsatz / Gefahrgut',
  BMA: 'Brandmeldeanlage',
  Hilfeleistung: 'Hilfeleistung',
  Fehlalarm: 'Fehlalarm',
  Brandsicherheitswache: 'Brandsicherheitswache',
};

export const EINSATZ_STATUS = ['aktiv', 'abgeschlossen', 'archiviert'] as const;

export type EinsatzStatus = (typeof EINSATZ_STATUS)[number];

export const EINSATZ_STATUS_LABELS: Record<EinsatzStatus, string> = {
  aktiv: 'Aktiv',
  abgeschlossen: 'Abgeschlossen',
  archiviert: 'Archiviert',
};

export const EINSATZ_FUNKTIONEN = [
  'Einsatzleiter',
  'Gruppenführer',
  'Maschinist',
  'Atemschutz',
  'Sicherheitstrupp',
  'Melder',
  'Wassertrupp',
  'Angriffstrupp',
  'Mannschaft',
  'Sonstiges',
] as const;

export type EinsatzFunktion = (typeof EINSATZ_FUNKTIONEN)[number];

export const ALARMIERUNG_ARTEN = [
  'ILS',
  'DME',
  'Telefon',
  'Vor_Ort',
  'Sonstiges',
] as const;

export type AlarmierungArt = (typeof ALARMIERUNG_ARTEN)[number];

export const ALARMIERUNG_ART_LABELS: Record<AlarmierungArt, string> = {
  ILS: 'ILS (Integrierte Leitstelle)',
  DME: 'Digitaler Meldeempfänger',
  Telefon: 'Telefon',
  Vor_Ort: 'Vor Ort',
  Sonstiges: 'Sonstiges',
};

// ---------------------------------------------------------------------------
// DATABASE ROW INTERFACES
// ---------------------------------------------------------------------------

/** Raw database row for einsaetze table */
export interface Einsatz {
  id: string;
  einsatz_nr: string;

  alarm_time: Date;
  ausrueck_time: Date | null;
  ankunft_time: Date | null;
  einrueck_time: Date | null;

  einsatz_art: EinsatzArt;
  einsatz_stichwort: string | null;

  strasse: string | null;
  hausnummer: string | null;
  ort: string | null;
  koordinaten: { x: number; y: number } | null; // pg returns POINT as {x,y}

  bericht_kurz: string | null;
  bericht_text: string | null;

  einsatzleiter_id: string | null;
  alarmierung_art: AlarmierungArt;
  status: EinsatzStatus;

  created_by: string | null;
  created_at: Date;
  updated_at: Date;
}

/** Assigned vehicle row */
export interface EinsatzFahrzeug {
  einsatz_id: string;
  fahrzeug_id: string;
  ausrueck_time: Date | null;
  einrueck_time: Date | null;
  assigned_at: Date;
  // Joined fields — aliased to 'kennzeichen' and 'fahrzeug_typ' in SQL query
  // to match the aliased SELECT in incident.service.ts
  kennzeichen?: string | null;       // aliased from amtliches_kennzeichen
  bezeichnung?: string;
  fahrzeug_typ?: string | null;      // aliased from typ_schluessel
}

/** Assigned personnel row */
export interface EinsatzPersonal {
  einsatz_id: string;
  user_id: string;
  funktion: EinsatzFunktion;
  alarm_time: Date | null;
  ankunft_time: Date | null;
  assigned_at: Date;
  // Joined fields
  name?: string | null;
  email?: string;
  given_name?: string | null;
  family_name?: string | null;
}

// ---------------------------------------------------------------------------
// EXTENDED TYPES (joins / computed)
// ---------------------------------------------------------------------------

/** Full incident with all related data — used by detail endpoint */
export interface EinsatzWithDetails extends Einsatz {
  einsatzleiter_name: string | null;
  fahrzeuge: EinsatzFahrzeug[];
  personal: EinsatzPersonal[];
  /** Hilfsfrist in minutes (alarm → arrival), null if ankunft_time not set */
  hilfsfrist_min: number | null;
  /** Total duration in minutes (alarm → return), null if einrueck_time not set */
  dauer_min: number | null;
}

/** Lightweight row for the list view DataGrid */
export interface EinsatzListItem {
  id: string;
  einsatz_nr: string;
  alarm_time: Date;
  einsatz_art: EinsatzArt;
  einsatz_stichwort: string | null;
  ort: string | null;
  strasse: string | null;
  status: EinsatzStatus;
  einsatzleiter_name: string | null;
  /** Hilfsfrist in minutes, null if ankunft_time not set */
  hilfsfrist_min: number | null;
  /** Total duration in minutes, null if einrueck_time not set */
  dauer_min: number | null;
  personal_count: number;
}

// ---------------------------------------------------------------------------
// STATISTICS TYPES
// ---------------------------------------------------------------------------

export interface MonthlyStatRow {
  monat: number;            // 1–12
  anzahl: number;
  avg_hilfsfrist_min: number | null;
  avg_dauer_min: number | null;
}

export interface EinsatzArtStatRow {
  einsatz_art: EinsatzArt;
  anzahl: number;
  avg_hilfsfrist_min: number | null;
}

export interface EinsatzStats {
  jahr: number;
  gesamt: number;
  abgeschlossen: number;
  aktiv: number;
  avg_hilfsfrist_min: number | null;
  /** Einsatzart with the highest count */
  haeufigste_art: EinsatzArt | null;
  monthly: MonthlyStatRow[];
  by_art: EinsatzArtStatRow[];
  /** Previous year monthly for chart overlay */
  prev_year_monthly: MonthlyStatRow[];
}

// ---------------------------------------------------------------------------
// ZOD VALIDATION SCHEMAS (Zod v4)
// ---------------------------------------------------------------------------

export const CreateEinsatzSchema = z.object({
  alarm_time: z.string().datetime({ offset: true }),
  ausrueck_time: z.string().datetime({ offset: true }).optional().nullable(),
  ankunft_time: z.string().datetime({ offset: true }).optional().nullable(),
  einrueck_time: z.string().datetime({ offset: true }).optional().nullable(),

  einsatz_art: z.enum(EINSATZ_ARTEN),
  einsatz_stichwort: z.string().max(30).optional().nullable(),

  strasse: z.string().max(150).optional().nullable(),
  hausnummer: z.string().max(20).optional().nullable(),
  ort: z.string().max(100).optional().nullable(),

  bericht_kurz: z.string().max(255).optional().nullable(),
  bericht_text: z.string().optional().nullable(),

  einsatzleiter_id: z.string().uuid().optional().nullable(),
  alarmierung_art: z.enum(ALARMIERUNG_ARTEN).optional().default('ILS'),
  status: z.enum(EINSATZ_STATUS).optional().default('aktiv'),
});

export type CreateEinsatzData = z.infer<typeof CreateEinsatzSchema>;

export const UpdateEinsatzSchema = CreateEinsatzSchema.partial().omit({
  alarm_time: true, // alarm_time can be updated but is handled explicitly
}).extend({
  // alarm_time is allowed to be updated but must remain valid if provided
  alarm_time: z.string().datetime({ offset: true }).optional(),
});

export type UpdateEinsatzData = z.infer<typeof UpdateEinsatzSchema>;

export const AssignPersonnelSchema = z.object({
  user_id: z.string().uuid(),
  funktion: z.enum(EINSATZ_FUNKTIONEN).optional().default('Mannschaft'),
  alarm_time: z.string().datetime({ offset: true }).optional().nullable(),
  ankunft_time: z.string().datetime({ offset: true }).optional().nullable(),
});

export type AssignPersonnelData = z.infer<typeof AssignPersonnelSchema>;

export const AssignVehicleSchema = z.object({
  fahrzeug_id: z.string().uuid(),
  ausrueck_time: z.string().datetime({ offset: true }).optional().nullable(),
  einrueck_time: z.string().datetime({ offset: true }).optional().nullable(),
});

export type AssignVehicleData = z.infer<typeof AssignVehicleSchema>;

export const IncidentFiltersSchema = z.object({
  dateFrom: z.string().datetime({ offset: true }).optional(),
  dateTo: z.string().datetime({ offset: true }).optional(),
  einsatzArt: z.enum(EINSATZ_ARTEN).optional(),
  status: z.enum(EINSATZ_STATUS).optional(),
  limit: z.coerce.number().int().min(1).max(200).optional().default(50),
  offset: z.coerce.number().int().min(0).optional().default(0),
});

export type IncidentFilters = z.infer<typeof IncidentFiltersSchema>;
