"use client";

import { ChangeEvent, useMemo, useRef, useState } from "react";
import * as XLSX from "xlsx";

type AssetOption = { id: string; plate?: string; model?: string; assetType?: string };
type DriverOption = { id: string; employeeNo?: string; firstName?: string; lastName?: string; status?: string };
type ImportRow = {
  sourceRow: number; date: string; assetId: string; assetLabel: string; distanceKm: number; fuelLiters: number;
  driverId: string; driverEmployeeNo: string; driverName: string; routeNote: string; error: string;
};

const normalize = (value: unknown) => String(value ?? "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
const compact = (value: unknown) => normalize(value).replace(/\s+/g, "");
const numberValue = (value: unknown) => {
  if (typeof value === "number") return value;
  return Number(String(value ?? "").replace(/\s/g, "").replace(",", ".").replace(/[^0-9.-]/g, ""));
};
const isoDate = (value: unknown) => {
  if (value instanceof Date && !Number.isNaN(value.getTime())) return value.toISOString().slice(0, 10);
  if (typeof value === "number") {
    const parsed = XLSX.SSF.parse_date_code(value);
    if (parsed) return `${parsed.y}-${String(parsed.m).padStart(2, "0")}-${String(parsed.d).padStart(2, "0")}`;
  }
  const raw = String(value ?? "").trim();
  if (/^\d{4}-\d{2}-\d{2}/.test(raw)) return raw.slice(0, 10);
  const match = raw.match(/^(\d{1,2})[\/.\-](\d{1,2})[\/.\-](\d{4})$/);
  return match ? `${match[3]}-${match[2].padStart(2, "0")}-${match[1].padStart(2, "0")}` : "";
};
function valueByAliases(row: Record<string, unknown>, aliases: string[]) {
  const normalized = aliases.map(normalize);
  return Object.entries(row).find(([key]) => normalized.includes(normalize(key)))?.[1] ?? "";
}

export default function FuelConsumptionImportModal({ assets, drivers, onClose, onImported }: { assets: AssetOption[]; drivers: DriverOption[]; onClose: () => void; onImported: () => Promise<void> | void }) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [fileName, setFileName] = useState(""), [rows, setRows] = useState<ImportRow[]>([]), [message, setMessage] = useState(""), [busy, setBusy] = useState(false);
  const validRows = useMemo(() => rows.filter(row => !row.error), [rows]);

  const downloadTemplate = (format: "xlsx" | "csv") => {
    const sample = [{ Date: "2026-08-01", "Matricule interne ou immatriculation": assets[0]?.id || "CAMI00000000", "Kilométrage parcouru (km)": 450, "Gasoil consommé (L)": 135.5, "Matricule chauffeur": drivers[0]?.employeeNo || "CHF-00001", Chauffeur: drivers[0] ? `${drivers[0].firstName || ""} ${drivers[0].lastName || ""}`.trim() : "Nom du chauffeur", "Trajet / observation": "Casablanca – Tanger – Casablanca" }];
    const sheet = XLSX.utils.json_to_sheet(sample);
    sheet["!cols"] = [{ wch: 15 }, { wch: 34 }, { wch: 28 }, { wch: 24 }, { wch: 23 }, { wch: 28 }, { wch: 45 }];
    if (format === "csv") {
      const blob = new Blob(["\ufeff" + XLSX.utils.sheet_to_csv(sheet, { FS: ";" })], { type: "text/csv;charset=utf-8" });
      const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = "modele-historique-consommation.csv"; link.click(); URL.revokeObjectURL(link.href);
    } else {
      const book = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(book, sheet, "Consommations"); XLSX.writeFile(book, "modele-historique-consommation.xlsx");
    }
  };

  const readFile = async (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]; if (!file) return;
    setMessage(""); setFileName(file.name);
    try {
      const workbook = XLSX.read(await file.arrayBuffer(), { type: "array", cellDates: true });
      const source = XLSX.utils.sheet_to_json<Record<string, unknown>>(workbook.Sheets[workbook.SheetNames[0]], { defval: "", raw: true });
      if (!source.length) throw new Error("Le fichier ne contient aucune ligne à importer.");
      if (source.length > 1000) throw new Error("Le fichier est limité à 1 000 lignes par import.");
      setRows(source.map((item, index): ImportRow => {
        const date = isoDate(valueByAliases(item, ["date", "date consommation", "date de consommation", "date prise", "date operation"]));
        const assetRaw = valueByAliases(item, ["matricule interne ou immatriculation", "matricule interne", "matricule", "immatriculation", "camion", "vehicule", "asset id"]);
        const assetKey = compact(assetRaw), asset = assets.find(candidate => [candidate.id, candidate.plate].some(value => compact(value) === assetKey));
        const distanceKm = numberValue(valueByAliases(item, [
          "kilometrage parcouru km",
          "kilometrage parcouru",
          "distance parcourue km",
          "distance parcourue",
          "distance km",
          "distance",
          "km parcourus",
        ]));
        const fuelLiters = numberValue(valueByAliases(item, [
          "gasoil consomme l",
          "gasoil consomme",
          "carburant consomme l",
          "carburant consomme",
          "quantite carburant",
          "litres consommes",
          "litres",
          "litrage",
          "fuel liters",
        ]));
        const driverNoRaw = valueByAliases(item, ["matricule chauffeur", "numero chauffeur", "driver id"]);
        const driverNameRaw = valueByAliases(item, ["chauffeur", "nom chauffeur", "driver"]);
        const driver = drivers.find(candidate => compact(candidate.employeeNo || candidate.id) === compact(driverNoRaw)) || drivers.find(candidate => compact(`${candidate.firstName || ""} ${candidate.lastName || ""}`) === compact(driverNameRaw));
        const errors: string[] = [];
        if (!date) errors.push("date invalide"); if (!asset) errors.push("véhicule inconnu");
        if (!Number.isFinite(distanceKm) || distanceKm <= 0) errors.push("kilométrage invalide");
        if (!Number.isFinite(fuelLiters) || fuelLiters <= 0) errors.push("litrage invalide");
        return { sourceRow: index + 2, date, assetId: asset?.id || "", assetLabel: asset ? `${asset.id} · ${asset.plate || ""}` : String(assetRaw || "Non renseigné"), distanceKm, fuelLiters, driverId: driver?.id || "", driverEmployeeNo: driver?.employeeNo || driver?.id || String(driverNoRaw || ""), driverName: driver ? `${driver.firstName || ""} ${driver.lastName || ""}`.trim() : String(driverNameRaw || ""), routeNote: String(valueByAliases(item, ["trajet observation", "trajet", "observation", "note"])), error: errors.join(" · ") };
      }));
    } catch (reason) { setRows([]); setMessage(reason instanceof Error ? reason.message : "Lecture du fichier impossible."); }
    finally { event.target.value = ""; }
  };

  const importRows = async () => {
    if (!validRows.length || busy) return; setBusy(true); setMessage("");
    try {
      const response = await fetch("/api/fuel-consumption", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ records: validRows }) });
      const data = await response.json(); if (!response.ok) throw new Error(data.error || "Import impossible.");
      await onImported(); setMessage(`${data.imported} ligne(s) importée(s)${data.skipped ? ` · ${data.skipped} doublon(s) ignoré(s)` : ""}.`);
      if (!data.errors?.length) window.setTimeout(onClose, 900);
    } catch (reason) { setMessage(reason instanceof Error ? reason.message : "Import impossible."); }
    finally { setBusy(false); }
  };

  return <div className="modal-backdrop" role="dialog" aria-modal="true"><section className="modal fuel-import-modal">
    <header className="modal-header"><div><p>REPRISE DE L’HISTORIQUE</p><h2>Importer les consommations camion</h2></div><button onClick={onClose} aria-label="Fermer">×</button></header>
    <div className="fuel-import-body">
      <section className="fuel-import-guide"><div><strong>1</strong><p><b>Téléchargez un modèle</b><span>Excel ou CSV avec les colonnes attendues.</span></p></div><div><strong>2</strong><p><b>Complétez puis chargez</b><span>Un aperçu contrôle les véhicules et les valeurs.</span></p></div><div><strong>3</strong><p><b>Validez l’import</b><span>Les doublons camion/date sont automatiquement ignorés.</span></p></div></section>
      <div className="fuel-import-actions"><button className="secondary-button" onClick={() => downloadTemplate("xlsx")}>↓ Modèle Excel</button><button className="secondary-button" onClick={() => downloadTemplate("csv")}>↓ Modèle CSV</button><input ref={inputRef} type="file" accept=".xlsx,.xls,.csv" onChange={readFile} hidden/><button className="primary-button" onClick={() => inputRef.current?.click()}>⇧ Choisir un fichier</button></div>
      {fileName && <div className="fuel-import-summary"><div><span>FICHIER ANALYSÉ</span><strong>{fileName}</strong></div><b className="ok">{validRows.length} prête(s)</b><b className={rows.length - validRows.length ? "bad" : "ok"}>{rows.length - validRows.length} à corriger</b></div>}
      {rows.length > 0 && <div className="fuel-import-preview"><div className="fuel-import-head"><span>Ligne</span><span>Date</span><span>Camion</span><span>Km</span><span>Litres</span><span>Chauffeur</span><span>Contrôle</span></div>{rows.slice(0, 100).map(row => <div className={row.error ? "fuel-import-row invalid" : "fuel-import-row"} key={row.sourceRow}><span>{row.sourceRow}</span><span>{row.date || "—"}</span><span>{row.assetLabel}</span><span>{Number.isFinite(row.distanceKm) ? row.distanceKm : "—"}</span><span>{Number.isFinite(row.fuelLiters) ? row.fuelLiters : "—"}</span><span>{row.driverName || row.driverEmployeeNo || "Non renseigné"}</span><span>{row.error || "Prête"}</span></div>)}</div>}
      {rows.length > 100 && <small className="fuel-import-more">Aperçu limité aux 100 premières lignes. Les {rows.length} lignes seront contrôlées.</small>}
      {message && <p className={message.includes("importée") ? "fuel-import-message success" : "fuel-import-message"}>{message}</p>}
    </div>
    <footer className="modal-actions"><button className="secondary-button" onClick={onClose}>Annuler</button><button className="primary-button" disabled={!validRows.length || busy} onClick={importRows}>{busy ? "Import en cours…" : `Importer ${validRows.length || ""} ligne(s)`}</button></footer>
  </section></div>;
}
