/* ============================================================
   TOS_API — SPA client for the TreasuryOS server API.
   Sessions ride an HTTP-only cookie (same origin), so no tokens
   are held in JS. Every call throws on non-2xx with the server's
   error message; callers decide whether to fall back to the
   in-browser parsers (offline/static mode).
   ============================================================ */
(function (global) {
  function jsonOrThrow(res) {
    return res.json().catch(function () { return {}; }).then(function (body) {
      if (!res.ok) throw new Error(body && body.error ? body.error : "Request failed (" + res.status + ")");
      return body;
    });
  }
  function postJson(url, payload) {
    return fetch(url, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload || {})
    }).then(jsonOrThrow);
  }
  function query(params) {
    var pairs = [];
    Object.keys(params || {}).forEach(function (key) {
      if (params[key] !== undefined && params[key] !== null && params[key] !== "") {
        pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
      }
    });
    return pairs.length ? "?" + pairs.join("&") : "";
  }

  global.TOS_API = {
    login: function (email, password) {
      return fetch("/api/auth/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email, password: password })
      }).then(jsonOrThrow);
    },
    logout: function () {
      return fetch("/api/auth/logout", { method: "POST" }).then(jsonOrThrow);
    },
    me: function () {
      return fetch("/api/auth/me").then(function (res) {
        if (res.status === 401 || res.status === 403) {
          return res.json().catch(function () { return {}; }).then(function (body) {
            var err = new Error(body && body.error ? body.error : "Session expired");
            err.auth = true;
            throw err;
          });
        }
        return jsonOrThrow(res);
      });
    },
    clear: function (kind) {
      return fetch("/api/submissions?kind=" + encodeURIComponent(kind), { method: "DELETE" }).then(jsonOrThrow);
    },
    upload: function (kind, file) {
      var form = new FormData();
      form.set("kind", kind);
      form.set("file", file);
      return fetch("/api/submissions", { method: "POST", body: form }).then(jsonOrThrow);
    },
    latest: function (kind) {
      return fetch("/api/submissions/latest?kind=" + encodeURIComponent(kind)).then(function (res) {
        if (res.status === 404) return null;
        return jsonOrThrow(res);
      });
    },
    list: function () {
      return fetch("/api/submissions").then(jsonOrThrow);
    },
    resetDemo: function () {
      return fetch("/api/demo/reset", { method: "POST" }).then(jsonOrThrow);
    },
    askAi: function (payload) {
      return postJson("/api/ai/ask", payload);
    },
    assumptionSets: function () {
      return fetch("/api/assumption-sets").then(jsonOrThrow);
    },
    createAssumptionSet: function (payload) {
      return postJson("/api/assumption-sets", payload);
    },
    submitAssumptionSet: function (id, payload) {
      return postJson("/api/assumption-sets/" + encodeURIComponent(id) + "/submit", payload);
    },
    decideAssumptionSet: function (id, payload) {
      return postJson("/api/assumption-sets/" + encodeURIComponent(id) + "/approval-decisions", payload);
    },
    calculationViews: function (filters) {
      return fetch("/api/calculation-views" + query(filters)).then(jsonOrThrow);
    },
    runCalculationView: function (payload) {
      return postJson("/api/calculation-views/run", payload);
    },
    calculationView: function (id) {
      return fetch("/api/calculation-views/" + encodeURIComponent(id)).then(jsonOrThrow);
    },
    calculationViewVariances: function (baseViewId, filters) {
      return fetch("/api/calculation-views/" + encodeURIComponent(baseViewId) + "/variance" + query(filters)).then(jsonOrThrow);
    },
    createCalculationViewVariance: function (baseViewId, payload) {
      return postJson("/api/calculation-views/" + encodeURIComponent(baseViewId) + "/variance", payload);
    },
    workItems: function () {
      return fetch("/api/work-items").then(jsonOrThrow);
    },
    auditEvents: function (filters) {
      return fetch("/api/audit-events" + query(filters)).then(jsonOrThrow);
    },
    liveReadiness: function () {
      return fetch("/api/live-readiness").then(jsonOrThrow);
    },
    domainEvents: function (filters) {
      return fetch("/api/domain-events" + query(filters)).then(jsonOrThrow);
    },
    evidenceDocuments: function (filters) {
      return fetch("/api/evidence-documents" + query(filters)).then(jsonOrThrow);
    },
    liquidityGaps: function (filters) {
      return fetch("/api/liquidity-gaps" + query(filters)).then(jsonOrThrow);
    },
    deriveLiquidityGap: function (payload) {
      return postJson("/api/liquidity-gaps", payload);
    },
    fundingActionRequests: function (filters) {
      return fetch("/api/funding-action-requests" + query(filters)).then(jsonOrThrow);
    },
    createFundingActionRequest: function (payload) {
      return postJson("/api/funding-action-requests", payload);
    },
    treasuryOperations: function (filters) {
      return fetch("/api/treasury-operations" + query(filters)).then(jsonOrThrow);
    },
    createBorrowingDeal: function (payload) {
      return postJson("/api/treasury-operations/deals", payload);
    },
    transitionTreasuryDeal: function (dealId, payload) {
      return postJson("/api/treasury-operations/deals/" + encodeURIComponent(dealId) + "/transitions", payload);
    },
    deliverSettlementInstructions: function (payload) {
      return postJson("/api/settlement-adapter/deliver", payload);
    },
    ingestSettlementConfirmation: function (payload) {
      return postJson("/api/settlement-adapter/confirmations", payload);
    },
    completeTreasuryDemoJourney: function (payload) {
      return postJson("/api/treasury-operations/demo-journey", payload);
    }
  };
})(window);
