/**
 * Screenshot the new interactive section cards (Vacation/Budget/Groups)
 * + the existing task quick-actions dialog (after the button-row fix)
 * + the complete-dialog (to investigate the user's "fields are missing" report).
 *
 * Creates a temporary Lovelace dashboard with all three cards, navigates,
 * captures shots in light + dark mode at desktop width.
 */
import { chromium } from "playwright";
import { promises as fs } from "fs";
import http from "http";
import path from "path";

const HA = "http://localhost:8125";
const OUT = path.resolve("../../../screenshots-section-cards");

async function getRefreshToken() {
  function post(p, body, ct = "application/json") {
    return new Promise((resolve, reject) => {
      const data = typeof body === "string" ? body : JSON.stringify(body);
      const opts = {
        hostname: "localhost", port: 8125, path: p, method: "POST",
        headers: { "Content-Type": ct, "Content-Length": Buffer.byteLength(data) },
      };
      const req = http.request(opts, (r) => {
        let d = "";
        r.on("data", (c) => (d += c));
        r.on("end", () => resolve(JSON.parse(d)));
      });
      req.on("error", reject);
      req.write(data);
      req.end();
    });
  }
  const flow = await post("/auth/login_flow", {
    client_id: HA + "/", handler: ["homeassistant", null], redirect_uri: HA + "/",
  });
  const auth = await post(`/auth/login_flow/${flow.flow_id}`, {
    client_id: HA + "/", username: "dev", password: "dev",
  });
  const tok = await post(
    "/auth/token",
    `grant_type=authorization_code&code=${auth.result}&client_id=${HA}/`,
    "application/x-www-form-urlencoded",
  );
  return tok.refresh_token;
}

async function ws(page, cmd) {
  return page.evaluate(async (c) => {
    const ha = document.querySelector("home-assistant");
    if (!ha?.hass?.connection) throw new Error("no hass connection");
    return await ha.hass.connection.sendMessagePromise(c);
  }, cmd);
}

async function ensureDashboard(page) {
  const dashboards = await ws(page, { type: "lovelace/dashboards/list" });
  const slug = "section-cards-test";
  const existing = dashboards.find((d) => d.url_path === slug);
  if (!existing) {
    await ws(page, {
      type: "lovelace/dashboards/create",
      url_path: slug,
      title: "Section Cards Test",
      icon: "mdi:test-tube",
      mode: "storage",
      show_in_sidebar: false,
      require_admin: false,
    });
  }
  // Save the lovelace config with our 3 cards
  await ws(page, {
    type: "lovelace/config/save",
    url_path: slug,
    config: {
      views: [
        {
          title: "Sections",
          path: "default",
          icon: "mdi:view-dashboard",
          cards: [
            { type: "custom:maintenance-vacation-section-card" },
            { type: "custom:maintenance-budget-section-card" },
            { type: "custom:maintenance-groups-section-card" },
          ],
        },
        {
          title: "Card",
          path: "card",
          icon: "mdi:card-text",
          cards: [
            { type: "custom:maintenance-supporter-card", show_actions: true, max_items: 6 },
          ],
        },
      ],
    },
  });
  return slug;
}

async function shot(page, name) {
  await page.waitForTimeout(800);
  const file = path.join(OUT, name + ".png");
  await page.screenshot({ path: file, fullPage: false });
  console.log(`  📸 ${name}.png`);
}

async function setColorScheme(page, scheme) {
  // Force HA's theme by injecting localStorage entry + reloading
  await page.evaluate((s) => {
    localStorage.setItem("selectedTheme", JSON.stringify({ dark: s === "dark" }));
  }, scheme);
}

async function main() {
  await fs.mkdir(OUT, { recursive: true });
  console.log("Getting refresh token…");
  const refreshToken = await getRefreshToken();

  const browser = await chromium.launch({ headless: true });

  for (const colorScheme of ["dark", "light"]) {
    console.log(`\n=== ${colorScheme} mode ===`);
    const ctx = await browser.newContext({
      viewport: { width: 1280, height: 900 },
      colorScheme,
      ignoreHTTPSErrors: true,
    });
    const page = await ctx.newPage();
    page.on("pageerror", (e) => console.log("PAGE ERROR:", e.message));
    page.on("console", (m) => {
      if (m.type() === "error") console.log("CONSOLE:", m.text());
    });

    await page.goto(HA);
    await page.waitForTimeout(800);
    await page.evaluate((args) => {
      localStorage.setItem("hassTokens", JSON.stringify({
        hassUrl: args.ha, clientId: args.ha + "/",
        refresh_token: args.r, access_token: "",
        token_type: "Bearer", expires_in: 1800, expires: 0,
      }));
      localStorage.setItem("selectedTheme", JSON.stringify({ dark: args.cs === "dark" }));
    }, { ha: HA, r: refreshToken, cs: colorScheme });

    await page.goto(HA);
    await page.waitForTimeout(3500);

    const slug = await ensureDashboard(page);
    await page.goto(`${HA}/${slug}/default`);
    await page.waitForTimeout(4000);

    await shot(page, `sections-${colorScheme}`);

    // Card view — click a task row to open quick-actions dialog
    await page.goto(`${HA}/${slug}/card`);
    await page.waitForTimeout(3500);
    await shot(page, `card-${colorScheme}`);

    // Find a task row that's likely to have adaptive data (Oil Change has the
    // longest history in the demo dataset). Falls back to first row.
    const taskClicked = await page.evaluate(() => {
      function findInAllShadows(root, sel) {
        if (!root) return null;
        if (root.querySelector?.(sel)) return root.querySelector(sel);
        for (const el of root.querySelectorAll?.("*") || []) {
          if (el.shadowRoot) {
            const found = findInAllShadows(el.shadowRoot, sel);
            if (found) return found;
          }
        }
        return null;
      }
      const card = findInAllShadows(document, "maintenance-supporter-card");
      if (!card?.shadowRoot) return "no card";
      const rows = Array.from(card.shadowRoot.querySelectorAll(".task-item.clickable"));
      if (rows.length === 0) return "no rows";
      // Prefer "Filter Replacement" (HVAC) — has interval recommendation,
      // then "Oil Change" (Family Car) — has sensor + long history.
      const filterReplace = rows.find((r) => /filter replacement|filter wechsel/i.test(r.textContent || ""));
      const oilChange = rows.find((r) => /oil change|ölwechsel/i.test(r.textContent || ""));
      const target = filterReplace || oilChange || rows[0];
      target.click();
      return "clicked: " + (target.querySelector(".task-name")?.textContent || "?");
    });

    console.log(`  Task row click: ${taskClicked}`);
    if (taskClicked.startsWith("clicked")) {
      // Wait for both /object load AND /settings (features) load — the stats
      // toggle only renders after features arrive
      await page.waitForTimeout(4000);
      await shot(page, `quick-actions-${colorScheme}`);

      // Click the 2nd link (= "Show stats + graphs")
      const statsClick = await page.evaluate(() => {
        const dlg = document.body.querySelector("maintenance-task-quick-actions-dialog");
        const links = dlg?.shadowRoot?.querySelectorAll(".details-toggle button.link") || [];
        if (links.length < 2) return `only ${links.length} link(s)`;
        links[1].click();
        return "clicked: " + (links[1].textContent || "").trim();
      });
      console.log(`  Stats toggle: ${statsClick}`);
      await page.waitForTimeout(1500);
      await shot(page, `quick-actions-stats-${colorScheme}`);

      // Capture the graphs section — scroll dialog and shoot again
      await page.evaluate(() => {
        const dlg = document.body.querySelector("maintenance-task-quick-actions-dialog");
        const inner = dlg?.shadowRoot?.querySelector(".dialog");
        if (inner) inner.scrollTop = Math.max(0, inner.scrollHeight - 700);
      }).catch(() => {});
      await page.waitForTimeout(400);
      await shot(page, `quick-actions-stats-bottom-${colorScheme}`);

      // Restore scroll for complete dialog test
      await page.evaluate(() => {
        const dlg = document.body.querySelector("maintenance-task-quick-actions-dialog");
        const inner = dlg?.shadowRoot?.querySelector(".dialog");
        if (inner) inner.scrollTop = 0;
      }).catch(() => {});
      await page.waitForTimeout(300);
      const completeClicked = await page.evaluate(() => {
        const dlg = document.body.querySelector("maintenance-task-quick-actions-dialog");
        if (!dlg?.shadowRoot) return "no quick-actions dialog on body";
        const btns = dlg.shadowRoot.querySelectorAll(".actions.primary-row button");
        // The first button in primary-row IS Complete
        if (btns.length === 0) return "no buttons in primary-row";
        btns[0].click();
        return "clicked: " + (btns[0].textContent || "").trim();
      });
      console.log(`  Complete click: ${completeClicked}`);
      await page.waitForTimeout(2000);
      await shot(page, `complete-dialog-${colorScheme}`);

      // Close everything
      await page.keyboard.press("Escape");
      await page.waitForTimeout(500);
    }

    await ctx.close();
  }

  await browser.close();
  console.log(`\nDone. Screenshots in ${OUT}`);
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
