import { XMLParser } from "fast-xml-parser";
import path from "node:path";
import fs from "node:fs/promises";

const URL = "https://www.jambox.pl/xml/mozliwosci.xml";

function isAuthorized(request) {
  const expected = import.meta.env.JAMBOX_ADMIN_TOKEN;
  if (!expected) return false; 
  const token = request.headers.get("x-admin-token");
  return token === expected;
}

function toArray(v) {
  if (!v) return [];
  return Array.isArray(v) ? v : [v];
}

function decodeEntities(input) {
  if (!input) return "";

  let s = String(input)
    .replace(/&nbsp;/g, " ")
    .replace(/&amp;/g, "&")
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">");

  s = s.replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d)));
  s = s.replace(/&#x([0-9a-fA-F]+);/g, (_, h) =>
    String.fromCodePoint(parseInt(h, 16)),
  );

  return s;
}

function parseHtmlContent(input) {
  if (!input) return [];

  let s = decodeEntities(String(input));

  s = s
    .replace(/<\s*(ul|ol)[^>]*>/gi, "\n__LIST_START__\n")
    .replace(/<\/\s*(ul|ol)\s*>/gi, "\n__LIST_END__\n")
    .replace(/<\s*li[^>]*>/gi, "__LI__")
    .replace(/<\/\s*li\s*>/gi, "\n");

  s = s
    .replace(/<\s*br\s*\/?\s*>/gi, "\n")
    .replace(/<\/\s*(p|div)\s*>/gi, "\n")
    .replace(/<\s*(p|div)[^>]*>/gi, "");

  s = s.replace(/<[^>]+>/g, "");

  s = s
    .replace(/\r/g, "")
    .replace(/[ \t]+\n/g, "\n")
    .replace(/\n{3,}/g, "\n\n")
    .trim();

  const blocks = [];
  const lines = s.split("\n");

  let textBuf = [];
  let listBuf = null;

  const flushText = () => {
    const txt = textBuf.join("\n").trim();
    if (txt) blocks.push({ type: "text", value: txt });
    textBuf = [];
  };

  const flushList = () => {
    if (listBuf && listBuf.length) {
      blocks.push({
        type: "list",
        items: listBuf.map((x) => x.trim()).filter(Boolean),
      });
    }
    listBuf = null;
  };

  for (const raw of lines) {
    const line = raw.trim();

    if (line === "__LIST_START__") {
      flushText();
      listBuf = [];
      continue;
    }

    if (line === "__LIST_END__") {
      flushList();
      continue;
    }

    if (listBuf && line.startsWith("__LI__")) {
      listBuf.push(line.replace("__LI__", "").trim());
      continue;
    }

    if (!line) {
      if (!listBuf) textBuf.push("");
      continue;
    }

    textBuf.push(line);
  }

  flushText();
  flushList();

  return blocks;
}

function blocksToMarkdown(blocks) {
  const out = [];

  for (const b of blocks) {
    if (b.type === "text") {
      const lines = b.value
        .replace(/\.\s+/g, ".\n")
        .split("\n")
        .map((x) => x.trim())
        .filter(Boolean);

      out.push(lines.join("\n"));
    }

    if (b.type === "list") {
      for (const item of b.items) {
        out.push(`- ${item}`);
      }
    }
  }

  return out.join("\n\n").trim();
}

function extractUrlsFromString(s) {
  return String(s).match(/https?:\/\/[^\s<"]+/g) ?? [];
}

function extractScreens(screen) {
  if (!screen) return [];
  if (typeof screen === "string") return extractUrlsFromString(screen);

  const divs = screen?.div;
  if (divs) {
    return toArray(divs)
      .map((d) => (typeof d === "string" ? d : d?.["#text"] ?? ""))
      .flatMap(extractUrlsFromString);
  }

  return extractUrlsFromString(JSON.stringify(screen));
}

function yamlQuote(v) {
  return `"${String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
}

function toYaml(sections) {
  const out = ["sections:"];

  for (const s of sections) {
    out.push(`  - title: ${yamlQuote(s.title)}`);
    if (s.image) out.push(`    image: ${yamlQuote(s.image)}`);
    out.push("    content: |");

    for (const line of String(s.content).split("\n")) {
      out.push(`      ${line}`);
    }

    out.push("");
  }

  return out.join("\n").trimEnd() + "\n";
}

export async function POST({ request }) {
  if (!isAuthorized(request)) {
    return new Response(JSON.stringify({ ok: false, error: "Unauthorized" }), {
      status: 401,
      headers: { "content-type": "application/json; charset=utf-8" },
    });
  }

  const res = await fetch(URL, {
    headers: { accept: "application/xml,text/xml,*/*" },
  });

  if (!res.ok) {
    return new Response(JSON.stringify({ ok: false, error: `JAMBOX XML: HTTP ${res.status}` }), {
      status: 502,
      headers: { "content-type": "application/json; charset=utf-8" },
    });
  }

  const xml = await res.text();
  const parser = new XMLParser({ trimValues: true });
  const parsed = parser.parse(xml);

  const nodes = toArray(parsed?.xml?.node ?? parsed?.node);

  const sections = nodes
    .map((n) => {
      const title = parseHtmlContent(n?.title)
        .map((b) => (b.type === "text" ? b.value : ""))
        .join(" ")
        .trim();

      if (!title) return null;

      const blocks = [...parseHtmlContent(n?.teaser), ...parseHtmlContent(n?.description)];

      const content = blocksToMarkdown(blocks);
      if (!content) return null;

      const screens = extractScreens(n?.screen);
      const image = screens?.[0];

      return { title, image, content };
    })
    .filter(Boolean);

  const outDir = path.join(process.cwd(), "src", "content", "internet-telewizja");
  const outFile = path.join(outDir, "telewizja-mozliwosci.yaml");

  await fs.mkdir(outDir, { recursive: true });
  await fs.writeFile(outFile, toYaml(sections), "utf8");

  return new Response(JSON.stringify({ ok: true, count: sections.length, file: outFile }), {
    headers: { "content-type": "application/json; charset=utf-8" },
  });
}
