/**
 * GL Accounts refresh — Office Script for Excel Web.
 *
 * Setup:
 *   1. Start the Python API:  uvicorn main:app --port 8000
 *   2. Expose via ngrok:      ngrok http 8000
 *   3. Paste the ngrok URL in API_BASE below.
 *   4. In Excel Web: Automate tab > New Script > paste > Save > Run.
 *
 * Sheet layout (GL_Accounts_Client_Template.xlsx):
 *   Setup!B6  = Company       Functions!C6  = get_account_base_amount
 *   Setup!B7  = Account       Functions!C7  = get_account_real_base_amount
 *   Setup!B8  = Currency      Functions!C8  = get_account_amount
 *   Setup!B9  = Date          Functions!C9  = get_account_abbr
 *                             Functions!C10 = get_account_name
 *                             Functions!C11 = get_account_contact
 *                             Functions!C12 = get_account_contact_code
 *                             Functions!C13 = get_account_contact_name
 */

interface GlResults {
  get_account_base_amount: number;
  get_account_real_base_amount: number;
  get_account_amount: number;
  get_account_abbr: string;
  get_account_name: string;
  get_account_contact: string;
  get_account_contact_code: string;
  get_account_contact_name: string;
}

interface GlResponse {
  results: GlResults;
  errors: { [key: string]: string };
}

async function main(workbook: ExcelScript.Workbook): Promise<void> {
  // ── CONFIG ─────────────────────────────────────────────────────────────────
  const API_BASE = "https://obscure-boggle-sprig.ngrok-free.dev";
  // ───────────────────────────────────────────────────────────────────────────

  const setupSheet = workbook.getWorksheet("Setup");
  const functionsSheet = workbook.getWorksheet("Functions");

  if (!setupSheet || !functionsSheet) {
    console.log("Error: 'Setup' or 'Functions' sheet not found.");
    return;
  }

  const company: string = String(setupSheet.getRange("B6").getValue());
  const account: string = String(setupSheet.getRange("B7").getValue());
  const currency: string = String(setupSheet.getRange("B8").getValue());
  const date: string = toIsoDate(setupSheet.getRange("B9").getValue());

  // Mark as loading
  for (let row = 6; row <= 13; row++) {
    functionsSheet.getRange("C" + row).setValue("...");
  }

  const url = API_BASE + "/gl/all"
    + "?company="  + encodeURIComponent(company)
    + "&account="  + encodeURIComponent(account)
    + "&currency=" + encodeURIComponent(currency)
    + "&date="     + encodeURIComponent(date);

  let data: GlResponse;

  try {
    const response = await fetch(url, {
      headers: { "ngrok-skip-browser-warning": "true" }
    });
    if (!response.ok) {
      throw new Error("HTTP " + response.status);
    }
    data = (await response.json()) as GlResponse;
  } catch (err) {
    console.log("API call failed: " + err);
    for (let row = 6; row <= 13; row++) {
      functionsSheet.getRange("C" + row).setValue("#API_ERROR");
    }
    return;
  }

  const r = data.results;
  functionsSheet.getRange("C6").setValue(r.get_account_base_amount !== null ? r.get_account_base_amount : "");
  functionsSheet.getRange("C7").setValue(r.get_account_real_base_amount !== null ? r.get_account_real_base_amount : "");
  functionsSheet.getRange("C8").setValue(r.get_account_amount !== null ? r.get_account_amount : "");
  functionsSheet.getRange("C9").setValue(r.get_account_abbr !== null ? r.get_account_abbr : "");
  functionsSheet.getRange("C10").setValue(r.get_account_name !== null ? r.get_account_name : "");
  functionsSheet.getRange("C11").setValue(r.get_account_contact !== null ? r.get_account_contact : "");
  functionsSheet.getRange("C12").setValue(r.get_account_contact_code !== null ? r.get_account_contact_code : "");
  functionsSheet.getRange("C13").setValue(r.get_account_contact_name !== null ? r.get_account_contact_name : "");

  console.log("Refreshed: " + company + " / " + account + " / " + currency + " / " + date);
}

function toIsoDate(value: string | number | boolean): string {
  if (typeof value === "number") {
    // Excel date serial → YYYY-MM-DD
    const d = new Date(Date.UTC(1899, 11, 30) + value * 86400000);
    return d.toISOString().split("T")[0];
  }
  const s = String(value);
  const d = new Date(s);
  if (!isNaN(d.getTime())) {
    return d.toISOString().split("T")[0];
  }
  return s;
}
