/*
  Register the USD reference rate in the multi-currency module (sandbox only).

  Enabling the module is not enough: an invoice can only carry a currency that
  exists in the module's rate table, otherwise Dolibarr silently falls back to
  EUR (observed: POST /invoices with multicurrency_code=USD returned EUR).

  The rate is the ECB EUR/USD reference of the day the invoice is settled —
  per the KM amendment, art. 2/4. It is written here so the invoice carries the
  contractual obligation ($2,500 / $3,000) rather than a drifting EUR value.
  The invoice then carries the obligation itself, not a counter-value.

  Run:
    DOLIBARR_ADDRESS=https://erp-sandbox.arcodange.lab \
      deno run -A test/sandboxCurrencySetup.ts --code USD --rate 1.14416
*/
import "load_dotenv";
import { chromium } from "playwright";
import login from "./scripts/login.ts";
import { assertSandbox } from "./scripts/guard.ts";

const argv = Deno.args;
const pick = (flag: string, dflt: string) =>
  argv.includes(flag) ? argv[argv.indexOf(flag) + 1] : dflt;
const code = pick("--code", "USD");
const rate = pick("--rate", "1.14416");
const shotDir = Deno.env.get("SHOT_DIR") ?? "/tmp";

const dolibarrAddress = assertSandbox();
console.log(`target: ${dolibarrAddress} (guard passed)`);

const adminCredentials = {
  username: Deno.env.get("DOLI_ADMIN_LOGIN") || "undefined",
  password: Deno.env.get("DOLI_ADMIN_PASSWORD") || "undefined",
};

const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({ locale: "fr-FR" });
const page = await context.newPage();

try {
  await login.doAdminLogin({ page, dolibarrAddress, adminCredentials });

  // The module's admin page moved across Dolibarr versions — probe the known
  // paths and report which one answers instead of assuming.
  const candidates = [
    "/multicurrency/admin/multicurrency.php",
    "/admin/multicurrency.php",
    "/multicurrency/admin/setup.php",
  ];
  let adminUrl = "";
  for (const p of candidates) {
    const resp = await page.goto(`${dolibarrAddress}${p}`, {
      waitUntil: "domcontentloaded",
    });
    const status = resp?.status() ?? 0;
    const isError = await page.locator("text=/Forbidden|not found|erreur/i")
      .count();
    console.log(`probe ${p} -> HTTP ${status}${isError ? " (error page)" : ""}`);
    if (status === 200 && !isError) {
      adminUrl = `${dolibarrAddress}${p}`;
      break;
    }
  }
  if (!adminUrl) {
    console.warn("no multicurrency admin page found — reporting only");
    await page.screenshot({ path: `${shotDir}/currency-probe.png` });
  } else {
    console.log(`admin page: ${adminUrl}`);
    // Add-rate form: a currency code field + a rate field, then submit.
    const codeInput = page.locator(
      'input[name="code"], select[name="code"], input[name="currency_code"]',
    ).first();
    const rateInput = page.locator(
      'input[name="rate"], input[name="value"], input[name="currency_rate"]',
    ).first();
    if (await codeInput.count() && await rateInput.count()) {
      const tag = await codeInput.evaluate((e) => e.tagName.toLowerCase());
      if (tag === "select") {
        await codeInput.selectOption({ label: new RegExp(code, "i") as never })
          .catch(async () => await codeInput.selectOption(code));
      } else {
        await codeInput.fill(code);
      }
      await rateInput.fill(rate);
      await page.locator('input[type="submit"], button[type="submit"]').first()
        .click();
      await page.waitForLoadState("networkidle");
      console.log(`submitted ${code} @ ${rate}`);
    } else {
      console.warn("add-rate form not recognised — reporting only");
    }
    await page.screenshot({ path: `${shotDir}/currency.png`, fullPage: true });
    console.log(await page.locator("body").innerText().then((t) =>
      t.split("\n").filter((l) => /USD|EUR|taux|rate/i.test(l)).slice(0, 8)
        .join(" | ")
    ));
  }
} finally {
  await context.close();
  await browser.close();
}
