/**
 * Self-test favorites MySQL module (toggle + list).
 */
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; role: string } };
}

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

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

  // Pick a published property from Mongo via public API
  const propsRes = await fetch(`http://127.0.0.1:${port}/api/properties?take=1`);
  const propsBody: any = await propsRes.json().catch(() => null);
  const propertyId =
    propsBody?.properties?.[0]?.id ||
    propsBody?.properties?.[0]?._id ||
    propsBody?.[0]?.id;
  if (!propertyId) throw new Error("no published property found for favorites test");

  // Ensure clean start
  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,
  });
  await conn.execute(`DELETE FROM favorites WHERE user_id = ? AND property_id = ?`, [
    auth.user.id,
    propertyId,
  ]);

  const addRes = await fetch(`${base}/toggle`, {
    method: "POST",
    headers,
    body: JSON.stringify({ propertyId }),
  });
  const addBody: any = await addRes.json().catch(() => null);
  const addOk =
    addRes.status === 200 && addBody?._db === "mysql" && addBody?.favorited === true;

  const listRes = await fetch(base, { headers });
  const listBody: any = await listRes.json().catch(() => null);
  const listOk =
    listRes.status === 200 &&
    listBody?._db === "mysql" &&
    Array.isArray(listBody.favorites) &&
    listBody.favorites.some((f: any) => f.property?.id === propertyId || f.property?._id === propertyId);

  const remRes = await fetch(`${base}/toggle`, {
    method: "POST",
    headers,
    body: JSON.stringify({ propertyId }),
  });
  const remBody: any = await remRes.json().catch(() => null);
  const remOk =
    remRes.status === 200 && remBody?._db === "mysql" && remBody?.favorited === false;

  const [rows] = await conn.query(
    `SELECT id FROM favorites WHERE user_id = ? AND property_id = ?`,
    [auth.user.id, propertyId],
  );
  const gone = (rows as unknown[]).length === 0;
  await conn.end();

  const results = [
    ["toggle_add", addOk],
    ["list", listOk],
    ["toggle_remove", remOk && gone],
  ] as const;
  for (const [name, pass] of results) {
    console.log(`${pass ? "PASS" : "FAIL"}  ${name}`);
  }
  const ok = results.every(([, p]) => p);
  console.log(`\nSUMMARY favorites: ${ok ? "3/3 pass" : "FAIL"}`);
  process.exit(ok ? 0 : 1);
}

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