import { z } from 'zod';

// ---------------------------------------------------------------------------
// Enums
// ---------------------------------------------------------------------------

export const BUCHUNGS_ARTEN = ['intern', 'extern', 'wartung', 'reservierung', 'sonstiges', 'lehrgang'] as const;
export type BuchungsArt = (typeof BUCHUNGS_ARTEN)[number];

// ---------------------------------------------------------------------------
// Core DB-mapped interfaces
// ---------------------------------------------------------------------------

export interface FahrzeugBuchung {
  id: string;
  fahrzeug_id: string;
  titel: string;
  beschreibung?: string | null;
  beginn: Date;
  ende: Date;
  buchungs_art: BuchungsArt;
  ganztaegig: boolean;
  gebucht_von: string;
  kontakt_person?: string | null;
  kontakt_telefon?: string | null;
  abgesagt: boolean;
  abgesagt_grund?: string | null;
  erstellt_am: Date;
  aktualisiert_am: Date;
  // Joined
  fahrzeug_name?: string | null;
  fahrzeug_kennzeichen?: string | null;
  gebucht_von_name?: string | null;
}

/** Lightweight list item — used in calendar and upcoming list widget */
export interface FahrzeugBuchungListItem {
  id: string;
  fahrzeug_id: string;
  fahrzeug_name: string;
  fahrzeug_kennzeichen?: string | null;
  titel: string;
  buchungs_art: BuchungsArt;
  beginn: Date;
  ende: Date;
  ganztaegig: boolean;
  abgesagt: boolean;
  gebucht_von: string;
  gebucht_von_name?: string | null;
}

// ---------------------------------------------------------------------------
// Zod validation schemas
// ---------------------------------------------------------------------------

const BuchungBaseSchema = z.object({
  fahrzeugId: z.string().uuid('fahrzeugId muss eine gueltige UUID sein'),
  titel: z.string().min(3, 'Titel muss mindestens 3 Zeichen haben').max(500),
  beschreibung: z.string().max(2000).optional().nullable(),
  beginn: z
    .string()
    .datetime({ offset: true, message: 'beginn muss ein ISO-8601 Datum mit Zeitzone sein' })
    .transform((s) => new Date(s)),
  ende: z
    .string()
    .datetime({ offset: true, message: 'ende muss ein ISO-8601 Datum mit Zeitzone sein' })
    .transform((s) => new Date(s)),
  buchungsArt: z.enum(BUCHUNGS_ARTEN).default('intern'),
  kontaktPerson: z.string().max(255).optional().nullable(),
  kontaktTelefon: z.string().max(50).optional().nullable(),
  ganztaegig: z.boolean().optional().default(false),
});

export const CreateBuchungSchema = BuchungBaseSchema.refine(
  (d) => d.ende > d.beginn,
  { message: 'Ende muss nach Beginn liegen', path: ['ende'] }
);
export type CreateBuchungData = z.infer<typeof CreateBuchungSchema>;

export const UpdateBuchungSchema = BuchungBaseSchema.partial().refine(
  (d) => d.ende == null || d.beginn == null || d.ende > d.beginn,
  { message: 'Ende muss nach Beginn liegen', path: ['ende'] }
);
export type UpdateBuchungData = z.infer<typeof UpdateBuchungSchema>;

export const CancelBuchungSchema = z.object({
  abgesagt_grund: z
    .string()
    .min(5, 'Bitte gib einen Stornierungsgrund an (min. 5 Zeichen)')
    .max(1000),
});
export type CancelBuchungData = z.infer<typeof CancelBuchungSchema>;
