// API client. Clerk session token is fetched at call time from window.Clerk.
// (Set up in app.jsx — Clerk loads from CDN and we keep the instance on
// window.__clerk.)

async function clerkToken() {
  const c = window.__clerk;
  if (!c?.session) return null;
  try { return await c.session.getToken(); }
  catch { return null; }
}

async function api(method, path, { body, multipart } = {}) {
  const headers = {};
  const token = await clerkToken();
  if (token) headers.Authorization = `Bearer ${token}`;

  let payload;
  if (multipart) {
    payload = body;
  } else if (body !== undefined) {
    headers['Content-Type'] = 'application/json';
    payload = JSON.stringify(body);
  }
  const resp = await fetch(path, { method, headers, body: payload });
  const text = await resp.text();
  let json;
  try { json = text ? JSON.parse(text) : null; } catch { json = { error: text }; }
  if (!resp.ok) {
    const err = new Error(json?.error || `HTTP ${resp.status}`);
    err.status = resp.status;
    err.body = json;
    throw err;
  }
  return json;
}

const Api = {
  // Session
  me: () => api('GET', '/api/auth/me'),
  config: () => api('GET', '/api/config'),

  // Credits / payments
  credits: () => api('GET', '/api/credits'),
  paypalCreateOrder: (packId) => api('POST', '/api/paypal/create-order', { body: { packId } }),
  paypalCaptureOrder: (orderId) => api('POST', '/api/paypal/capture-order', { body: { orderId } }),

  // Projects (designs)
  listProjects: () => api('GET', '/api/projects'),
  getProject: (id) => api('GET', `/api/projects/${id}`),
  publicProject: (id) => api('GET', `/api/public/projects/${id}`),
  deleteProject: (id) => api('DELETE', `/api/projects/${id}`),

  // Paints
  listPaints: () => api('GET', '/api/paints'),

  // Collections (named subsets of the catalogue that preselect paints)
  listCollections: () => api('GET', '/api/collections'),
  createCollection: (name, paintIds) => api('POST', '/api/collections', { body: { name, paintIds } }),
  updateCollection: (id, { name, paintIds }) => api('PUT', `/api/collections/${id}`, { body: { name, paintIds } }),
  deleteCollection: (id) => api('DELETE', `/api/collections/${id}`),

  // Upload + generation
  uploadImage: (file) => {
    const fd = new FormData();
    fd.append('image', file);
    return api('POST', '/api/upload', { body: fd, multipart: true });
  },
  newFromBase: (baseUrl) => api('POST', '/api/projects/new-from-base', { body: { baseUrl } }),
  generateScheme: ({ projectId, imageUrl, paints, difficulty, complexity }) =>
    api('POST', '/api/generate-scheme', { body: { projectId, imageUrl, paints, difficulty, complexity } }),
  generatePaintedImage: ({ projectId, imageUrl, scheme, difficulty }) =>
    api('POST', '/api/generate-painted-image', { body: { projectId, imageUrl, scheme, difficulty } }),
  generateSteps: ({ projectId, scheme, difficulty, paints, complexity }) =>
    api('POST', '/api/generate-steps', { body: { projectId, scheme, difficulty, paints, complexity } }),
};

window.Api = Api;
