export const API_BASE = "/api/v1";

export type Entity = {
  id: string;
  created_at: string;
  updated_at: string;
};

export type Customer = Entity & {
  customer_type: "practice" | "clinic";
  name: string;
  city?: string | null;
  phone?: string | null;
  email?: string | null;
  hygiene_officer?: string | null;
  quality_manager?: string | null;
  notes?: string | null;
};

export type Location = Entity & {
  customer_id: string;
  name: string;
  street?: string | null;
  postal_code?: string | null;
  city?: string | null;
  room?: string | null;
};

export type Contact = Entity & {
  customer_id: string;
  full_name: string;
  function?: string | null;
  email?: string | null;
  phone?: string | null;
};

export type Device = Entity & {
  customer_id: string;
  location_id?: string | null;
  manufacturer: string;
  model: string;
  serial_number: string;
  device_type?: string | null;
  year_built?: number | null;
  commissioned_on?: string | null;
  chamber_volume_liters?: number | null;
  steam_generation?: string | null;
  water_treatment?: string | null;
  documentation?: string | null;
  supplier?: string | null;
};

export type Equipment = Entity & {
  kind: string;
  manufacturer?: string | null;
  model?: string | null;
  serial_number: string;
  calibrated_on?: string | null;
  calibration_due_on?: string | null;
  certificate_document_id?: string | null;
  status: "green" | "yellow" | "red";
};

export type User = Entity & {
  email: string;
  first_name: string;
  last_name: string;
  role: "admin" | "pruefer" | "mitarbeiter" | "leser";
  is_active: boolean;
  must_change_password: boolean;
  last_login_at?: string | null;
  password_changed_at?: string | null;
};

export type ValidationItem = Entity & {
  report_number: string;
  customer_id: string;
  location_id?: string | null;
  contact_id?: string | null;
  device_id?: string | null;
  validation_type: string;
  project?: string | null;
  test_location?: string | null;
  examiner_name?: string | null;
  participants?: string | null;
  operator_name?: string | null;
  status: string;
  result?: string | null;
  scheduled_on?: string | null;
  performed_on?: string | null;
  next_validation_on?: string | null;
  revalidation_interval_months: number;
  next_validation_manually_overridden: boolean;
  version: number;
  previous_validation_id?: string | null;
  equipment_ids: string[];
  environment_conditions: Record<string, unknown>;
  documentation_checklist: Record<string, unknown>[];
  performance_checklist: Record<string, unknown>[];
  programs: Record<string, unknown>[];
  loading_patterns: Record<string, unknown>[];
  measurement_data: Record<string, unknown>[];
  drying: Record<string, unknown>;
  recommendations: Record<string, unknown>[];
  attachments: Record<string, unknown>[];
};

export function normalizeValidationPayload<T extends Record<string, unknown>>(values: T): T {
  const optionalForeignKeys = ["contact_id", "examiner_id"];
  return {
    ...values,
    ...Object.fromEntries(optionalForeignKeys.map((key) => [key, values[key] || null]))
  };
}

export type Paginated<T> = {
  items: T[];
  total: number;
  page: number;
  page_size: number;
};

export async function login(email: string, password: string) {
  const response = await fetch(`/api/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email, password }),
    credentials: "include"
  });
  if (!response.ok) {
    const detail = await response.text();
    const error = new Error(detail || `HTTP ${response.status}`) as Error & { status?: number };
    error.status = response.status;
    throw error;
  }
  return response.json() as Promise<{ user: User; expires_in: number }>;
}

export async function apiGet<T>(path: string, token: string): Promise<T> {
  const response = await fetch(`${API_BASE}${path}`, {
    cache: "no-store",
    credentials: "include"
  });
  if (!response.ok) {
    throw new Error(`API request failed: ${response.status}`);
  }
  return response.json() as Promise<T>;
}

export async function apiSend<T>(path: string, token: string, method: "POST" | "PUT", body: unknown): Promise<T> {
  const response = await fetch(`${API_BASE}${path}`, {
    method,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
    credentials: "include"
  });
  if (!response.ok) {
    const detail = await response.text();
    throw new Error(detail || `API request failed: ${response.status}`);
  }
  return response.json() as Promise<T>;
}

export async function apiDelete(path: string, token: string): Promise<void> {
  const response = await fetch(`${API_BASE}${path}`, {
    method: "DELETE",
    credentials: "include"
  });
  if (!response.ok) {
    throw new Error(`API request failed: ${response.status}`);
  }
}

export async function apiFetch<T>(path: string, token: string, init?: RequestInit): Promise<T> {
  const response = await fetch(`${API_BASE}${path}`, {
    ...init,
    headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) },
    credentials: "include"
  });
  if (!response.ok) {
    throw new Error(await response.text());
  }
  return response.json() as Promise<T>;
}
