/**
 * Self-test properties MySQL GET cases + create/soft-delete draft.
 */
import fs from "fs";
import path from "path";
import mysql from "mysql2/promise";

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;
  }
}

async function login(email: string, password: string) {
  const port = process.env.PORT || "4000";
  const res = await fetch(`http://127.0.0.1:${port}/api/auth/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email, password }),
  });
  const body: any = await res.json().catch(() => null);
  if (!res.ok || !body?.accessToken) {
    throw new Error(`login failed status=${res.status} ${JSON.stringify(body)}`);
  }
  return body as { accessToken: string; user: { id: string } };
}

async function getJson(url: string, headers?: Record<string, string>) {
  const res = await fetch(url, { headers });
  const body: any = await res.json().catch(() => null);
  return { status: res.status, body };
}

async function main() {
  loadEnv();
  const port = process.env.PORT || "4000";
  const base = `http://127.0.0.1:${port}/api/properties`;
  const results: { name: string; pass: boolean; detail: string }[] = [];
  const check = (name: string, pass: boolean, detail: string) => {
    results.push({ name, pass, detail });
    console.log(`${pass ? "PASS" : "FAIL"}  ${name} — ${detail}`);
  };

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

  {
    const { status, body } = await getJson(`${base}?featured=true&take=6`);
    check(
      "featured",
      status === 200 && body?._db === "mysql" && Array.isArray(body?.properties),
      `count=${body?.properties?.length}`,
    );
  }

  {
    const { status, body } = await getJson(`${base}?city=${encodeURIComponent("Tunis")}`);
    check(
      "city_filter",
      status === 200 && body?._db === "mysql" && Array.isArray(body?.properties),
      `count=${body?.properties?.length}`,
    );
  }

  {
    const { status, body } = await getJson(`${base}?city=${encodeURIComponent("zzzz-no-city-xyz")}`);
    check(
      "city_no_results",
      status === 200 && body?._db === "mysql" && body?.properties?.length === 0,
      `count=${body?.properties?.length}`,
    );
  }

  let sampleId = "";
  {
    const { status, body } = await getJson(`${base}?take=1`);
    sampleId = body?.properties?.[0]?.id || "";
    const detail = await getJson(`${base}/${sampleId}`);
    check(
      "get_by_id",
      detail.status === 200 &&
        detail.body?._db === "mysql" &&
        (detail.body?.property?.id === sampleId || detail.body?.property?._id === sampleId),
      `id=${sampleId} status=${detail.status}`,
    );
  }

  const auth = await login("admin@safarlibya.com", "19992000");
  const headers = {
    Authorization: `Bearer ${auth.accessToken}`,
    "Content-Type": "application/json",
  };

  const conn = await mysql.createConnection({
    host: process.env.MYSQL_HOST,
    port: Number(process.env.MYSQL_PORT),
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
    database: process.env.MYSQL_DATABASE,
  });
  const [cities] = await conn.query(`SELECT id FROM cities WHERE deleted_at IS NULL LIMIT 1`);
  const cityId = (cities as any[])[0]?.id;
  if (!cityId) throw new Error("no city for property create test");

  const marker = `mysql-prop-test-${Date.now()}`;
  const createRes = await fetch(base, {
    method: "POST",
    headers,
    body: JSON.stringify({
      cityId,
      titleAr: marker,
      titleEn: marker,
      descriptionAr: "وصف اختبار عقارات MySQL طويل بما يكفي",
      descriptionEn: "MySQL properties self-test description long enough",
      address: "Test Address 123",
      bedrooms: 1,
      bathrooms: 1,
      maxGuests: 2,
      basePriceTnd: 99,
      status: "DRAFT",
      images: [{ url: "https://example.com/test.jpg", sortOrder: 0 }],
    }),
  });
  const createBody: any = await createRes.json().catch(() => null);
  const createdId = createBody?.property?.id || createBody?.property?._id;
  const createOk =
    createRes.status === 201 && createBody?._db === "mysql" && !!createdId;

  check("create_draft", createOk, `status=${createRes.status} id=${createdId}`);

  if (createdId) {
    const delRes = await fetch(`${base}/${createdId}`, { method: "DELETE", headers });
    const delBody: any = await delRes.json().catch(() => null);
    const [rows] = await conn.query(
      `SELECT deleted_at, status FROM properties WHERE id = ?`,
      [createdId],
    );
    const soft = (rows as any[])[0];
    check(
      "soft_delete",
      delRes.status === 200 &&
        delBody?._db === "mysql" &&
        soft?.deleted_at != null &&
        soft?.status === "PAUSED",
      `status=${delRes.status}`,
    );
  } else {
    check("soft_delete", false, "skipped — no created id");
  }

  await conn.end();

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

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