// api.jsx — HTTP client. Attaches to window.API.

(function () {
  const BASE = window.__API_BASE__ || "http://localhost:4000";
  const TOKEN_KEY = "ct_access_token";

  function getToken() {
    try { return localStorage.getItem(TOKEN_KEY); } catch { return null; }
  }
  function setToken(t) {
    if (t) localStorage.setItem(TOKEN_KEY, t);
    else localStorage.removeItem(TOKEN_KEY);
  }
  function clearToken() { setToken(null); }

  function qs(obj) {
    if (!obj) return "";
    const parts = [];
    for (const [k, v] of Object.entries(obj)) {
      if (v === undefined || v === null || v === "") continue;
      parts.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return parts.length ? "?" + parts.join("&") : "";
  }

  async function request(method, path, { body, query, headers } = {}) {
    const url = BASE + path + qs(query);
    const opts = {
      method,
      headers: { "Accept": "application/json", ...(headers || {}) },
      credentials: "include",
    };
    const token = getToken();
    if (token) opts.headers["Authorization"] = "Bearer " + token;
    if (body !== undefined && !(body instanceof FormData)) {
      opts.headers["Content-Type"] = "application/json";
      opts.body = JSON.stringify(body);
    } else if (body instanceof FormData) {
      opts.body = body;
    }

    let resp;
    try {
      resp = await fetch(url, opts);
    } catch (e) {
      const err = new Error("Network error");
      err.code = "NETWORK";
      err.statusCode = 0;
      throw err;
    }

    const text = await resp.text();
    let payload = null;
    if (text) {
      try { payload = JSON.parse(text); } catch { payload = { raw: text }; }
    }

    if (!resp.ok) {
      if (resp.status === 401) {
        clearToken();
        window.dispatchEvent(new CustomEvent("ct:logout"));
      }
      const err = new Error((payload && payload.message) || resp.statusText || "Request failed");
      err.code = (payload && payload.error) || "ERROR";
      err.statusCode = resp.status;
      err.details = payload && payload.details;
      throw err;
    }

    return payload && "data" in payload ? payload : { data: payload };
  }

  const get = (path, query) => request("GET", path, { query });
  const post = (path, body) => request("POST", path, { body });
  const patch = (path, body) => request("PATCH", path, { body });
  const put = (path, body) => request("PUT", path, { body });
  const del = (path) => request("DELETE", path);

  const API = {
    base: BASE,
    getToken, setToken, clearToken,
    request,

    auth: {
      login: (email, password) => post("/auth/login", { email, password }),
      signup: (payload) => post("/auth/signup", payload),
      logout: () => post("/auth/logout"),
      refresh: () => post("/auth/refresh"),
      me: () => get("/auth/me"),
      updateMe: (payload) => patch("/auth/me", payload),
      changePassword: (currentPassword, newPassword) =>
        patch("/auth/me/password", { currentPassword, newPassword }),
    },

    onboarding: {
      status: () => get("/onboarding/status"),
      workspace: (payload) => post("/onboarding/workspace", payload),
      number: (payload) => post("/onboarding/number", payload),
      fund: (payload) => post("/onboarding/fund", payload),
    },

    workspaces: {
      list: () => get("/workspaces"),
      create: (payload) => post("/workspaces", payload),
      get: (wid) => get(`/workspaces/${wid}`),
      update: (wid, payload) => patch(`/workspaces/${wid}`, payload),
      delete: (wid) => del(`/workspaces/${wid}`),
    },

    dashboard: {
      stats: (wid, range) => get(`/workspaces/${wid}/dashboard/stats`, { range }),
      callVolume: (wid, range) => get(`/workspaces/${wid}/dashboard/call-volume`, { range }),
      callerMix: (wid, range) => get(`/workspaces/${wid}/dashboard/caller-mix`, { range }),
      geographic: (wid, range) => get(`/workspaces/${wid}/dashboard/geographic`, { range }),
      topNumbers: (wid, range, limit) => get(`/workspaces/${wid}/dashboard/top-numbers`, { range, limit }),
      topSources: (wid, range, limit) => get(`/workspaces/${wid}/dashboard/top-sources`, { range, limit }),
      recentCalls: (wid, limit) => get(`/workspaces/${wid}/dashboard/recent-calls`, { limit }),
    },

    calls: {
      list: (wid, query) => get(`/workspaces/${wid}/calls`, query),
      get: (wid, cid) => get(`/workspaces/${wid}/calls/${cid}`),
      transcript: (wid, cid) => get(`/workspaces/${wid}/calls/${cid}/transcript`),
      summary: (wid, cid) => get(`/workspaces/${wid}/calls/${cid}/summary`),
      patch: (wid, cid, payload) => patch(`/workspaces/${wid}/calls/${cid}`, payload),
      addTag: (wid, cid, tag) => post(`/workspaces/${wid}/calls/${cid}/tags`, { tag }),
      removeTag: (wid, cid, tag) => del(`/workspaces/${wid}/calls/${cid}/tags/${encodeURIComponent(tag)}`),
      listNotes: (wid, cid) => get(`/workspaces/${wid}/calls/${cid}/notes`),
      addNote: (wid, cid, content) => post(`/workspaces/${wid}/calls/${cid}/notes`, { content }),
      updateNote: (wid, cid, nid, content) => patch(`/workspaces/${wid}/calls/${cid}/notes/${nid}`, { content }),
      deleteNote: (wid, cid, nid) => del(`/workspaces/${wid}/calls/${cid}/notes/${nid}`),
      assign: (wid, cid, userId) => post(`/workspaces/${wid}/calls/${cid}/assign`, { userId }),
      unassign: (wid, cid) => del(`/workspaces/${wid}/calls/${cid}/assign`),
    },

    numbers: {
      list: (wid, query) => get(`/workspaces/${wid}/numbers`, query),
      create: (wid, payload) => post(`/workspaces/${wid}/numbers`, payload),
      get: (wid, nid) => get(`/workspaces/${wid}/numbers/${nid}`),
      patch: (wid, nid, payload) => patch(`/workspaces/${wid}/numbers/${nid}`, payload),
      delete: (wid, nid) => del(`/workspaces/${wid}/numbers/${nid}`),
    },

    inventory: {
      suggestions: (limit) => get("/inventory/numbers/suggestions", { limit }),
      search: (query) => get("/inventory/numbers/search", query),
      browse: (query) => get("/inventory/numbers/browse", query),
      check: (number) => get(`/inventory/numbers/check/${encodeURIComponent(number)}`),
    },

    routing: {
      list: (wid, query) => get(`/workspaces/${wid}/routing`, query),
      get: (wid, nid) => get(`/workspaces/${wid}/routing/${nid}`),
      put: (wid, nid, payload) => put(`/workspaces/${wid}/routing/${nid}`, payload),
      addIvr: (wid, nid, payload) => post(`/workspaces/${wid}/routing/${nid}/ivr`, payload),
      updateIvr: (wid, nid, oid, payload) => put(`/workspaces/${wid}/routing/${nid}/ivr/${oid}`, payload),
      deleteIvr: (wid, nid, oid) => del(`/workspaces/${wid}/routing/${nid}/ivr/${oid}`),
    },

    campaigns: {
      list: (wid) => get(`/workspaces/${wid}/campaigns`),
      create: (wid, payload) => post(`/workspaces/${wid}/campaigns`, payload),
      get: (wid, cid) => get(`/workspaces/${wid}/campaigns/${cid}`),
      patch: (wid, cid, payload) => patch(`/workspaces/${wid}/campaigns/${cid}`, payload),
      delete: (wid, cid) => del(`/workspaces/${wid}/campaigns/${cid}`),
    },

    team: {
      list: (wid) => get(`/workspaces/${wid}/team`),
      get: (wid, mid) => get(`/workspaces/${wid}/team/${mid}`),
      invite: (wid, payload) => post(`/workspaces/${wid}/team/invite`, payload),
      accept: (wid) => post(`/workspaces/${wid}/team/accept`),
      patch: (wid, mid, payload) => patch(`/workspaces/${wid}/team/${mid}`, payload),
      remove: (wid, mid) => del(`/workspaces/${wid}/team/${mid}`),
      resetPassword: (wid, mid) => post(`/workspaces/${wid}/team/${mid}/reset-password`),
    },

    billing: {
      balance: (wid) => get(`/workspaces/${wid}/billing/balance`),
      transactions: (wid, query) => get(`/workspaces/${wid}/billing/transactions`, query),
      summary: (wid) => get(`/workspaces/${wid}/billing/summary`),
      topup: (wid, payload) => post(`/workspaces/${wid}/billing/topup`, payload),
      paymentMethods: (wid) => get(`/workspaces/${wid}/billing/payment-methods`),
      addPaymentMethod: (wid, payload) => post(`/workspaces/${wid}/billing/payment-methods`, payload),
      removePaymentMethod: (wid, pmId) => del(`/workspaces/${wid}/billing/payment-methods/${pmId}`),
      setDefaultPaymentMethod: (wid, pmId) => post(`/workspaces/${wid}/billing/payment-methods/${pmId}/set-default`),
      autoReload: (wid) => get(`/workspaces/${wid}/billing/auto-reload`),
      updateAutoReload: (wid, payload) => patch(`/workspaces/${wid}/billing/auto-reload`, payload),
    },

    whitelabel: {
      get: (wid) => get(`/workspaces/${wid}/whitelabel`),
      patch: (wid, payload) => patch(`/workspaces/${wid}/whitelabel`, payload),
      uploadLogo: (wid, file) => {
        const fd = new FormData();
        fd.append("file", file);
        return request("POST", `/workspaces/${wid}/whitelabel/logo`, { body: fd });
      },
      deleteLogo: (wid) => del(`/workspaces/${wid}/whitelabel/logo`),
    },

    apiKeys: {
      list: (wid) => get(`/workspaces/${wid}/api-keys`),
      create: (wid, payload) => post(`/workspaces/${wid}/api-keys`, payload),
      revoke: (wid, keyId) => post(`/workspaces/${wid}/api-keys/${keyId}/revoke`),
      delete: (wid, keyId) => del(`/workspaces/${wid}/api-keys/${keyId}`),
    },

    webhooks: {
      list: (wid) => get(`/workspaces/${wid}/webhooks`),
      create: (wid, payload) => post(`/workspaces/${wid}/webhooks`, payload),
      patch: (wid, hid, payload) => patch(`/workspaces/${wid}/webhooks/${hid}`, payload),
      delete: (wid, hid) => del(`/workspaces/${wid}/webhooks/${hid}`),
      deliveries: (wid, hid, query) => get(`/workspaces/${wid}/webhooks/${hid}/deliveries`, query),
    },

    integrations: {
      list: (wid) => get(`/workspaces/${wid}/integrations`),
      connect: (wid, provider, config) => post(`/workspaces/${wid}/integrations/${provider}/connect`, { config }),
      patch: (wid, provider, payload) => patch(`/workspaces/${wid}/integrations/${provider}`, payload),
      disconnect: (wid, provider) => del(`/workspaces/${wid}/integrations/${provider}`),
    },

    settings: {
      get: (wid) => get(`/workspaces/${wid}/settings`),
      patch: (wid, payload) => patch(`/workspaces/${wid}/settings`, payload),
    },
  };

  window.API = API;
})();
