/**
 * Self-test notifications MySQL module.
 */
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 main() {
  loadEnv();
  const port = process.env.PORT || "4000";
  const base = `http://127.0.0.1:${port}/api/notifications`;

  // Prefer admin known from seed/ensure-admin; fall back to first user with password in MySQL is not available.
  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 marker = `notif-selftest-${Date.now()}`;
  const id = `test${Date.now().toString(36)}`;
  await conn.execute(
    `INSERT INTO notifications
      (id, user_id, title_ar, title_en, message_ar, message_en, link, read_at, created_at)
     VALUES (?,?,?,?,?,?,?,NULL,UTC_TIMESTAMP(3))`,
    [id, auth.user.id, marker, marker, "ar", "en", "/test"],
  );

  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.notifications) &&
    listBody.notifications.some((n: any) => n.titleEn === marker || n.titleAr === marker);

  const readRes = await fetch(`${base}/${id}/read`, { method: "POST", headers });
  const readBody: any = await readRes.json().catch(() => null);
  const readOk = readRes.status === 200 && readBody?._db === "mysql" && readBody?.ok === true;

  const [afterRead] = await conn.query(
    `SELECT read_at FROM notifications WHERE id = ? LIMIT 1`,
    [id],
  );
  const persistedRead = !!(afterRead as any[])[0]?.read_at;

  const readAllRes = await fetch(`${base}/read-all`, { method: "POST", headers });
  const readAllBody: any = await readAllRes.json().catch(() => null);
  const readAllOk =
    readAllRes.status === 200 && readAllBody?._db === "mysql" && readAllBody?.ok === true;

  await conn.execute(`DELETE FROM notifications WHERE id = ? OR title_en = ?`, [id, marker]);
  await conn.end();

  const results = [
    ["list", listOk],
    ["mark_read", readOk && persistedRead],
    ["read_all", readAllOk],
  ] as const;

  for (const [name, pass] of results) {
    console.log(`${pass ? "PASS" : "FAIL"}  ${name}`);
  }
  const ok = results.every(([, p]) => p);
  console.log(`\nSUMMARY notifications: ${ok ? "3/3 pass" : "FAIL"}`);
  process.exit(ok ? 0 : 1);
}

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