const STORAGE_KEY = 'sc-session-token';

function getStoredToken() {
  return window.localStorage.getItem(STORAGE_KEY);
}

function storeToken(token) {
  window.localStorage.setItem(STORAGE_KEY, token);
}

async function requestSessionToken() {
  const response = await fetch('/api/session');
  if (!response.ok) {
    throw new Error(`Failed to create session: ${response.status}`);
  }

  const payload = await response.json();
  storeToken(payload.token);
  return payload.token;
}

export async function ensureSession() {
  return getStoredToken() ?? await requestSessionToken();
}

async function authenticatedFetch(path, options = {}, retry = true) {
  const token = await ensureSession();
  const headers = new Headers(options.headers ?? {});
  headers.set('Authorization', `Bearer ${token}`);
  if (options.body && !headers.has('Content-Type')) {
    headers.set('Content-Type', 'application/json');
  }

  const response = await fetch(path, {
    ...options,
    headers
  });

  if (response.status === 401 && retry) {
    const nextToken = await requestSessionToken();
    return await authenticatedFetch(path, {
      ...options,
      headers: {
        ...(options.headers ?? {}),
        Authorization: `Bearer ${nextToken}`
      }
    }, false);
  }

  if (!response.ok) {
    let detail = '';
    try {
      const payload = await response.json();
      detail = payload.error ?? JSON.stringify(payload);
    } catch {
      detail = await response.text();
    }

    throw new Error(detail || `Request failed: ${response.status}`);
  }

  if (response.status === 204) {
    return null;
  }

  return await response.json();
}

export const api = {
  ensureSession,
  getState: () => authenticatedFetch('/api/state'),
  getTickets: () => authenticatedFetch('/api/tickets'),
  getTicket: (id) => authenticatedFetch(`/api/tickets/${id}`),
  completeTicket: (id, branchId = null) =>
    authenticatedFetch(`/api/tickets/${id}/complete`, {
      method: 'POST',
      body: JSON.stringify(branchId ? { branchId } : {})
    }),
  getMail: () => authenticatedFetch('/api/mail'),
  getMailById: (id) => authenticatedFetch(`/api/mail/${id}`),
  markMailRead: (id) => authenticatedFetch(`/api/mail/${id}/read`, { method: 'POST' }),
  replyMail: (id, choice) =>
    authenticatedFetch(`/api/mail/${id}/reply`, {
      method: 'POST',
      body: JSON.stringify({ choice })
    }),
  getDocs: () => authenticatedFetch('/api/docs'),
  getDoc: (id) => authenticatedFetch(`/api/docs/${id}`),
  getVms: () => authenticatedFetch('/api/vms'),
  askSage: (message) =>
    authenticatedFetch('/api/sage/message', {
      method: 'POST',
      body: JSON.stringify({ message })
    }),
  getProfile: () => authenticatedFetch('/api/profile'),
  setProfile: (portrait) =>
    authenticatedFetch('/api/profile', {
      method: 'PUT',
      body: JSON.stringify({ portrait })
    })
};
