// Components/CompanyImporters/QuickImporter.jsx
import { useRouter } from "next/router";
import { useState } from "react";
import axios from "axios";
import ImportShell from "./ImportShell";

const TOKEN = process.env.NEXT_PUBLIC_SECRET_TOKEN;
const IMPORT_API = "/api/Policy/Import";

export default function QuickImporter({ company }) {
  const router = useRouter();

  const [fileName, setFileName] = useState("");
  const [parsing, setParsing] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [parsed, setParsed] = useState([]);
  const [error, setError] = useState("");
  const [result, setResult] = useState(null);

  const onPickFile = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setError("");
    setResult(null);
    setFileName(file.name);
    setParsing(true);

    try {
      const xmlText = await file.text();
      const policies = parseQuickXmlToPolicies(xmlText, company.name);
      setParsed(policies);
    } catch (err) {
      console.error(err);
      setError(err?.message || "XML dosyası okunamadı.");
      setParsed([]);
    } finally {
      setParsing(false);
    }
  };

  const uploadToDb = async () => {
    if (!parsed.length) return;
    setUploading(true);
    setError("");
    setResult(null);

    try {
      const { data } = await axios.post(
        IMPORT_API,
        { policies: parsed },
        { headers: { Authorization: TOKEN ? `Bearer ${TOKEN}` : "" } }
      );

      if (!data?.success) throw new Error(data?.message || "Upload failed");
      setResult(data);
    } catch (e) {
      console.error(e);
      setError(
        e?.response?.data?.message ||
          e?.response?.data?.error ||
          e?.message ||
          "Upload error"
      );
    } finally {
      setUploading(false);
    }
  };

  return (
    <ImportShell
      company={company}
      fileName={fileName}
      parsing={parsing}
      uploading={uploading}
      parsedCount={parsed.length}
      error={error}
      result={result}
      onPickFile={onPickFile}
      onUpload={uploadToDb}
      onBack={() => router.push("/Policy")}
    />
  );
}

/* ---------------- Quick XML -> Policy mapping ---------------- */

function parseQuickXmlToPolicies(xmlText, agencyName) {
  if (!xmlText || !String(xmlText).trim()) return [];

  const parser = new DOMParser();
  const doc = parser.parseFromString(xmlText, "application/xml");

  // XML parse error?
  const parseErr = doc.querySelector("parsererror");
  if (parseErr) throw new Error("XML formatı hatalı görünüyor.");

  const policeNodes = Array.from(doc.querySelectorAll("Police"));
  if (!policeNodes.length) throw new Error("XML içinde <Police> bulunamadı.");

  return policeNodes.map((policeEl) => mapPoliceNodeToPolicy(policeEl, agencyName));
}

function mapPoliceNodeToPolicy(policeEl, agencyName) {
  const policeNo = text(policeEl, "PoliceNo");
  const zeyilNo = text(policeEl, "ZeyilNo") || "0";
  const yenilemeNo = toInt(text(policeEl, "YenilemeNo")) || 0;

  const urunKod = text(policeEl, "UrunKod");
  const urunAd = text(policeEl, "UrunAd");

  const brutPrim = toNum(text(policeEl, "BrutPrimTL") || text(policeEl, "BrutPrim"));
  const netPrim = toNum(text(policeEl, "NetPrimTL") || text(policeEl, "NetPrim"));
  const komisyon = toNum(text(policeEl, "AcenteKomisyonTL") || text(policeEl, "AcenteKomisyon"));

  const startdate = toDate(text(policeEl, "BaslamaTarihi"));
  const enddate = toDate(text(policeEl, "BitisTarihi"));
  const tanzimTarihi = toDate(text(policeEl, "TanzimTarihi"));

  const krediKartmi = text(policeEl, "KrediKartmi"); // "1" or "0"
  const kullanici = text(policeEl, "Kullanici"); // could be representative/assignment

  // insured / person
  const sigortaliEl = policeEl.querySelector("Sigortalilar > Sigortali");
  const insured =
    (sigortaliEl ? text(sigortaliEl, "SigortaliAd") : "") ||
    text(policeEl, "SigortaEttirenAd") ||
    "-";

  const nationalId =
    (sigortaliEl ? text(sigortaliEl, "Tckn") : "") ||
    text(policeEl, "Tckn") ||
    null;

  const phone = sigortaliEl ? cleanPhone(text(sigortaliEl, "Gsm")) : null;
  const birthDate = sigortaliEl ? toDate(text(sigortaliEl, "DogumTarihi")) : null;

  // questions (UrunSorular)
  const q = readQuestions(policeEl);

  const plateNo = q("PLAKA NO");
  const ilKodu = q("PLAKA İL KODU") || q("PLAKA IL KODU");
  const plate = buildPlate(ilKodu, plateNo);

  const brand = q("MARKA");
  const brandType = q("TIP") || q("TİP");
  const modelYear = toInt(q("MODEL YILI"));
  const motorNo = q("MOTOR NO");
  const chassisNo = q("SASI NO") || q("ŞASİ NO");
  const usageType = q("EGM KULLANIM ŞEKLİ") || q("KULLANIM ŞEKLİ") || q("KULLANIM SEKLI");

  const policyStatus = text(policeEl, "ZeyilTipAd") || "Police";

  // required fields in your schema:
  // agency, startdate, enddate, insured, policyEndorsementNo, product, plate, premium, assignments, paymentStatus
  return {
    agency: agencyName,

    startdate: startdate || tanzimTarihi || null,
    enddate: enddate || null,

    insured: String(insured).trim() || "-",
    policyEndorsementNo: [policeNo, zeyilNo].filter(Boolean).join("-"),

    product: String(urunAd || urunKod || "-").trim(),
    plate: String(plate || "-").trim(),

    // prefer brut for premium
    premium: brutPrim ?? netPrim ?? null,

    assignments: String(kullanici || "-").trim() || "-",
    paymentStatus: krediKartmi === "1" ? "Kredi Kartı" : "-",

    grossPremium: brutPrim ?? null,
    netPremium: netPrim ?? null,
    commission: komisyon ?? null,

    branch: null,
    representative: String(kullanici || "").trim() || null,
    policyStatus: String(policyStatus || "").trim() || null,
    renewed: yenilemeNo > 0,

    // optional details
    brand: brand || null,
    brandType: brandType || null,
    modelYear: modelYear ?? null,
    motorNo: motorNo || null,
    chassisNo: chassisNo || null,
    usageType: usageType || null,
    vehicleValue: null,
    licenseSerialNo: null,
    inspectionDate: null,
    productCode: String(urunKod || "").trim() || null,
    phone: phone || null,
    nationalId: nationalId ? String(nationalId).trim() : null,
    birthDate: birthDate || null,
  };
}

/* ---------------- helpers ---------------- */

function text(root, tag) {
  const el = root.querySelector(tag);
  return el?.textContent?.trim() ?? "";
}

function toNum(v) {
  if (v === null || v === undefined || v === "") return null;
  const n = Number(String(v).trim().replace(",", "."));
  return Number.isFinite(n) ? n : null;
}

function toInt(v) {
  if (!v) return null;
  const n = Number(String(v).replace(/[^\d-]/g, ""));
  return Number.isFinite(n) ? n : null;
}

function toDate(v) {
  if (!v) return null;
  const d = new Date(String(v).trim());
  return Number.isNaN(d.getTime()) ? null : d;
}

function cleanPhone(s) {
  const v = String(s || "").trim();
  if (!v) return null;
  return v.replace(/\s+/g, " ").replace(/[^\d+ -]/g, "");
}

function readQuestions(policeEl) {
  const list = Array.from(policeEl.querySelectorAll("UrunSorular > Soru"));
  const map = new Map();

  for (const node of list) {
    const ad = (node.querySelector("SoruAd")?.textContent || "").trim();
    const cevap = (node.querySelector("SoruCevap")?.textContent || "").trim();
    if (!ad) continue;
    map.set(norm(ad), cevap);
  }

  // returns by "contains" match (flexible)
  return (needle) => {
    const n = norm(needle);
    if (map.has(n)) return map.get(n);

    for (const [k, v] of map.entries()) {
      if (k.includes(n)) return v;
    }
    return "";
  };
}

function norm(s) {
  return String(s || "")
    .toUpperCase()
    .replace(/\u00A0/g, " ")
    .replace(/[İI]/g, "I")
    .replace(/Ş/g, "S")
    .replace(/Ğ/g, "G")
    .replace(/Ü/g, "U")
    .replace(/Ö/g, "O")
    .replace(/Ç/g, "C")
    .replace(/[–—]/g, "-")
    .replace(/\s+/g, " ")
    .trim();
}

function buildPlate(ilKodu, plateNo) {
  const pn = String(plateNo || "").trim();
  const ik = String(ilKodu || "").trim();

  if (!pn && !ik) return "";

  const city = ik ? String(Number(ik)) : ""; // "063" -> "63"
  if (!pn) return city;

  // If plate already starts with digits, return it
  if (/^\d/.test(pn)) return pn;

  // Otherwise prefix city code if available
  return city ? `${city} ${pn}` : pn;
}