import { z } from 'zod';

// ============================================================
// Domain enumerations — used both as Zod schemas and runtime
// arrays (for building <Select> options in the frontend).
// ============================================================

export const DIENSTGRAD_VALUES = [
  'Jugendfeuerwehrmann',
  'Probefeuerwehrmann',
  'Feuerwehrmann',
  'Oberfeuerwehrmann',
  'Hauptfeuerwehrmann',
  'Löschmeister',
  'Oberlöschmeister',
  'Hauptlöschmeister',
  'Brandmeister',
  'Oberbrandmeister',
  'Hauptbrandmeister',
  'Brandinspektor',
  'Oberbrandinspektor',
  'Verwaltungsmeister',
  'Oberverwaltungsmeister',
  'Hauptverwaltungsmeister',
  'Verwalter',
  'Sachbearbeiter',
  'Abschnittssachbearbeiter',
] as const;

export const STATUS_VALUES = [
  'aktiv',
  'kind',
  'jugend',
  'reserve',
] as const;

export const FUNKTION_VALUES = [
  'Kommandant',
  'Stellv. Kommandant',
  'Gruppenführer',
  'Truppführer',
  'Gerätewart',
  'Kassier',
  'Schriftführer',
  'Atemschutzwart',
  'Ausbildungsbeauftragter',
] as const;

export const TSHIRT_GROESSE_VALUES = [
  'XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL',
] as const;

export type DienstgradEnum = typeof DIENSTGRAD_VALUES[number];
export type StatusEnum = typeof STATUS_VALUES[number];
export type FunktionEnum = typeof FUNKTION_VALUES[number];
export type TshirtGroesseEnum = typeof TSHIRT_GROESSE_VALUES[number];

// ============================================================
// Core DB row interface — mirrors the mitglieder_profile table
// exactly (snake_case, nullable columns use `| null`)
// ============================================================
export interface MitgliederProfile {
  id: string;
  user_id: string;

  fdisk_standesbuch_nr: string | null;
  dienstgrad: DienstgradEnum | null;
  dienstgrad_seit: Date | null;
  funktion: FunktionEnum[];
  status: StatusEnum;

  eintrittsdatum: Date | null;
  austrittsdatum: Date | null;
  geburtsdatum: Date | null;       // sensitive field

  telefon_mobil: string | null;
  telefon_privat: string | null;

  notfallkontakt_name: string | null;    // sensitive field
  notfallkontakt_telefon: string | null; // sensitive field

  fuehrerscheinklassen: string[];
  tshirt_groesse: TshirtGroesseEnum | null;
  schuhgroesse: string | null;
  bemerkungen: string | null;
  bild_url: string | null;

  // FDISK-synced extended profile fields
  geburtsort: string | null;
  geschlecht: string | null;  // full text, e.g. 'männlich', 'weiblich'
  beruf: string | null;
  wohnort: string | null;
  plz: string | null;

  created_at: Date;
  updated_at: Date;
}

// ============================================================
// Rank-change history row
// ============================================================
export interface DienstgradVerlaufEntry {
  id: string;
  user_id: string;
  dienstgrad_neu: string;
  dienstgrad_alt: string | null;
  datum: Date;
  durch_user_id: string | null;
  bemerkung: string | null;
  created_at: Date;
}

// ============================================================
// Joined view: users row + mitglieder_profile (nullable)
// This is what the service returns for GET /members/:userId
// ============================================================
export interface MemberWithProfile {
  // --- from users ---
  id: string;
  email: string;
  name: string | null;
  given_name: string | null;
  family_name: string | null;
  preferred_username: string | null;
  profile_picture_url: string | null;
  is_active: boolean;
  last_login_at: Date | null;
  created_at: Date;

  // --- from mitglieder_profile (null when no profile exists) ---
  profile: MitgliederProfile | null;

  // --- rank history (populated on detail requests) ---
  dienstgrad_verlauf?: DienstgradVerlaufEntry[];
}

// ============================================================
// List-view projection — only the fields needed for the table
// ============================================================
export interface MemberListItem {
  // user fields
  id: string;
  name: string | null;
  given_name: string | null;
  family_name: string | null;
  email: string;
  profile_picture_url: string | null;
  is_active: boolean;

  // profile fields (null when no profile exists)
  profile_id: string | null;
  fdisk_standesbuch_nr: string | null;
  dienstgrad: DienstgradEnum | null;
  funktion: FunktionEnum[];
  status: StatusEnum | null;
  eintrittsdatum: Date | null;
  telefon_mobil: string | null;
}

// ============================================================
// Filter parameters for getAllMembers()
// ============================================================
export interface MemberFilters {
  search?: string;           // matches name, email, fdisk_standesbuch_nr
  status?: StatusEnum[];
  dienstgrad?: DienstgradEnum[];
  page?: number;             // 1-based
  pageSize?: number;
}

// ============================================================
// Zod validation schemas
// ============================================================

/**
 * Schema for POST /members/:userId/profile
 * All fields are optional at creation except user_id (in URL).
 * status has a default; every other field may be omitted.
 */
export const CreateMemberProfileSchema = z.object({
  fdisk_standesbuch_nr: z.string().max(32).optional(),
  dienstgrad: z.enum(DIENSTGRAD_VALUES).optional(),
  dienstgrad_seit: z.coerce.date().optional(),
  funktion: z.array(z.enum(FUNKTION_VALUES)).default([]),
  status: z.enum(STATUS_VALUES).default('aktiv'),
  eintrittsdatum: z.coerce.date().optional(),
  austrittsdatum: z.coerce.date().optional(),
  geburtsdatum: z.coerce.date().optional(),
  telefon_mobil: z.string().max(32).optional(),
  telefon_privat: z.string().max(32).optional(),
  notfallkontakt_name: z.string().max(255).optional(),
  notfallkontakt_telefon: z.string().max(32).optional(),
  fuehrerscheinklassen: z.array(z.string().max(8)).default([]),
  tshirt_groesse: z.enum(TSHIRT_GROESSE_VALUES).optional(),
  schuhgroesse: z.string().max(8).optional(),
  bemerkungen: z.string().optional(),
  bild_url: z.string().url().optional(),
});

export type CreateMemberProfileData = z.infer<typeof CreateMemberProfileSchema>;

/**
 * Schema for PATCH /members/:userId
 * Every field is optional — only provided fields are written.
 */
export const UpdateMemberProfileSchema = CreateMemberProfileSchema.partial();

export type UpdateMemberProfileData = z.infer<typeof UpdateMemberProfileSchema>;

/**
 * Schema for the "self-edit" subset available to the Mitglied role.
 * Only non-sensitive, personally-owned fields.
 */
export const SelfUpdateMemberProfileSchema = z.object({
  telefon_mobil: z.string().max(32).optional(),
  telefon_privat: z.string().max(32).optional(),
  notfallkontakt_name: z.string().max(255).optional(),
  notfallkontakt_telefon: z.string().max(32).optional(),
  tshirt_groesse: z.enum(TSHIRT_GROESSE_VALUES).optional(),
  schuhgroesse: z.string().max(8).optional(),
  bild_url: z.string().url().optional(),
  fdisk_standesbuch_nr: z.string().max(32).optional(),
});

export type SelfUpdateMemberProfileData = z.infer<typeof SelfUpdateMemberProfileSchema>;

// ============================================================
// Stats response shape (for dashboard KPI endpoint)
// ============================================================
export interface MemberStats {
  total: number;
  aktiv: number;
  kind: number;
  jugend: number;
  reserve: number;
}
