/**
 * Import klientów/polis z CSV -- port logiki z lokalnego MVP (src/clients.py).
 * Ta sama elastyczna mapa nagłówków (PL/EN warianty), żeby import działał
 * z eksportu z różnych systemów (Insly, Berg System, Excel) bez ręcznego
 * dopasowywania kolumn.
 */

export const HEADER_ALIASES: Record<string, string[]> = {
  name: ["klient", "imie i nazwisko", "imię i nazwisko", "nazwa klienta", "name", "client"],
  product: ["produkt", "linia", "typ ubezpieczenia", "product", "line"],
  insurer: ["towarzystwo", "tu", "ubezpieczyciel", "insurer", "company"],
  expiry_date: [
    "data wygasniecia",
    "data wygaśnięcia",
    "koniec ochrony",
    "expiry",
    "expiry_date",
    "end date",
    "data konca",
  ],
  contact: ["kontakt", "telefon", "email", "e-mail", "contact", "phone"],
};

function normalize(header: string): string {
  return header.trim().toLowerCase();
}

function mapHeaders(fieldnames: string[]): Record<string, string> {
  const normalized = new Map(fieldnames.map((h) => [normalize(h), h]));
  const mapping: Record<string, string> = {};
  for (const [target, aliases] of Object.entries(HEADER_ALIASES)) {
    for (const alias of aliases) {
      const hit = normalized.get(alias);
      if (hit) {
        mapping[target] = hit;
        break;
      }
    }
  }
  return mapping;
}

/** Próbuje rozpoznać datę w kilku popularnych formatach, zwraca ISO albo null. */
export function parseExpiry(raw: string | undefined): string | null {
  const value = (raw || "").trim();
  if (!value) return null;

  // YYYY-MM-DD
  let m = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (m) return value;

  // DD.MM.YYYY / DD-MM-YYYY / DD/MM/YYYY
  m = value.match(/^(\d{2})[.\-/](\d{2})[.\-/](\d{4})$/);
  if (m) {
    const [, d, mo, y] = m;
    return `${y}-${mo}-${d}`;
  }

  return null;
}

function splitCsvLine(line: string, delimiter: string): string[] {
  // Prosty parser CSV wystarczający dla eksportów bez cudzysłowów
  // zawierających sam separator w wartości -- zgodny z zakresem MVP.
  const cells = line.split(delimiter).map((c) => c.trim().replace(/^"|"$/g, ""));
  return cells;
}

export interface ParsedClient {
  name: string;
  product: string;
  insurer: string;
  expiry_date: string | null;
  contact: string;
}

export function parseClientsCsv(text: string): { clients: ParsedClient[]; warnings: string[] } {
  const warnings: string[] = [];
  const lines = text.split(/\r?\n/).filter((l) => l.trim().length > 0);
  if (lines.length === 0) {
    throw new Error("Plik CSV wygląda na pusty.");
  }

  const sample = lines[0];
  const delimiter = (sample.match(/;/g) || []).length > (sample.match(/,/g) || []).length ? ";" : ",";

  const fieldnames = splitCsvLine(lines[0], delimiter);
  const mapping = mapHeaders(fieldnames);

  if (!mapping.name) {
    throw new Error(
      'Nie znaleziono kolumny z nazwą klienta. Oczekiwane nagłówki to np. "Klient", "Imię i nazwisko".'
    );
  }

  const idx = (key: string) => fieldnames.indexOf(mapping[key]);
  const clients: ParsedClient[] = [];

  for (let i = 1; i < lines.length; i++) {
    const row = splitCsvLine(lines[i], delimiter);
    const name = mapping.name ? (row[idx("name")] || "").trim() : "";
    if (!name) continue;

    const expiryRaw = mapping.expiry_date ? row[idx("expiry_date")] : undefined;
    const expiryIso = parseExpiry(expiryRaw);
    if (expiryRaw && !expiryIso) {
      warnings.push(`Nie rozpoznano daty "${expiryRaw}" dla klienta ${name} -- zapisano bez daty.`);
    }

    clients.push({
      name,
      product: mapping.product ? (row[idx("product")] || "").trim() : "",
      insurer: mapping.insurer ? (row[idx("insurer")] || "").trim() : "",
      expiry_date: expiryIso,
      contact: mapping.contact ? (row[idx("contact")] || "").trim() : "",
    });
  }

  return { clients, warnings };
}

export function daysUntil(expiryIso: string | null): number | null {
  if (!expiryIso) return null;
  const target = new Date(expiryIso + "T00:00:00");
  if (Number.isNaN(target.getTime())) return null;
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const diffMs = target.getTime() - today.getTime();
  return Math.round(diffMs / (1000 * 60 * 60 * 24));
}
