/**
 * Self-test cities MySQL routes (GET cases).
 */
import fs from "fs";
import path from "path";

function loadEnv() {
  const t = fs.readFileSync(path.join(process.cwd(), ".env"), "utf8");
  for (const line of t.split(/\r?\n/)) {
    const s = line.trim();
    if (!s || s.startsWith("#")) continue;
    const eq = s.indexOf("=");
    if (eq <= 0) continue;
    const k = s.slice(0, eq).trim();
    let v = s.slice(eq + 1).trim();
    if (
      (v.startsWith('"') && v.endsWith('"')) ||
      (v.startsWith("'") && v.endsWith("'"))
    )
      v = v.slice(1, -1);
    process.env[k] = v;
  }
}

type Result = { name: string; pass: boolean; detail: string };

async function getJson(url: string) {
  const res = await fetch(url);
  const text = await res.text();
  let body: any = null;
  try {
    body = JSON.parse(text);
  } catch {
    body = text;
  }
  return { status: res.status, body };
}

async function main() {
  loadEnv();
  const port = process.env.PORT || "4000";
  const base = `http://127.0.0.1:${port}/api/cities`;
  const results: Result[] = [];

  const check = (name: string, pass: boolean, detail: string) => {
    results.push({ name, pass, detail });
    console.log(`${pass ? "PASS" : "FAIL"}  ${name} — ${detail}`);
  };

  // 1) list
  {
    const { status, body } = await getJson(base);
    check(
      "list",
      status === 200 &&
        Array.isArray(body?.cities) &&
        body.cities.length >= 1 &&
        body._db === "mysql",
      `status=${status} count=${body?.cities?.length} _db=${body?._db}`,
    );
  }

  // 2) EN
  {
    const { status, body } = await getJson(`${base}?q=${encodeURIComponent("Tunis")}`);
    const hit = (body?.cities || []).some(
      (c: any) => String(c.nameEn || "").toLowerCase().includes("tunis"),
    );
    check("search_en", status === 200 && hit && body._db === "mysql", `hit=${hit} _db=${body?._db}`);
  }

  // 3) AR
  {
    const { status, body } = await getJson(`${base}?q=${encodeURIComponent("تونس")}`);
    const hit = (body?.cities || []).length > 0;
    check("search_ar", status === 200 && hit && body._db === "mysql", `count=${body?.cities?.length}`);
  }

  // 4) alias
  {
    const { status, body } = await getJson(`${base}?q=${encodeURIComponent("العاصمة")}`);
    const hit = (body?.cities || []).some((c: any) => String(c.nameEn) === "Tunis");
    check("search_alias", status === 200 && hit && body._db === "mysql", `hit=${hit}`);
  }

  // 5) slug
  {
    const { status, body } = await getJson(`${base}?q=${encodeURIComponent("tunis")}`);
    const hit = (body?.cities || []).some((c: any) => String(c.slug).toLowerCase() === "tunis");
    check("search_slug", status === 200 && hit && body._db === "mysql", `hit=${hit}`);
  }

  // 6) tourist filter
  {
    const { status, body } = await getJson(`${base}?tourist=true`);
    const allTourist = (body?.cities || []).every((c: any) => c.isTourist === true);
    check(
      "filter_tourist",
      status === 200 && (body?.cities || []).length > 0 && allTourist && body._db === "mysql",
      `count=${body?.cities?.length} allTourist=${allTourist}`,
    );
  }

  // 7) empty search
  {
    const { status, body } = await getJson(
      `${base}?q=${encodeURIComponent("zzznomatchcity999")}`,
    );
    check(
      "search_no_results",
      status === 200 && Array.isArray(body?.cities) && body.cities.length === 0 && body._db === "mysql",
      `count=${body?.cities?.length}`,
    );
  }

  const failed = results.filter((r) => !r.pass).length;
  console.log(`\nSUMMARY cities: ${results.length - failed}/${results.length} pass (failed=${failed})`);
  process.exit(failed === 0 ? 0 : 1);
}

main().catch((e) => {
  console.error(e instanceof Error ? e.message : e);
  process.exit(1);
});
