const API_BASE = '/api';

function getToken(): string | null {
  return sessionStorage.getItem('sub-router-token');
}

export function setToken(token: string) {
  sessionStorage.setItem('sub-router-token', token);
}

export function clearToken() {
  sessionStorage.removeItem('sub-router-token');
}

async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
  const token = getToken();
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(options.headers as Record<string, string> || {}),
  };
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  const res = await fetch(`${API_BASE}${path}`, { ...options, headers });

  if (res.status === 401) {
    clearToken();
    window.location.reload();
    throw new Error('Unauthorized');
  }

  if (!res.ok) {
    const body = await res.json().catch(() => ({ error: res.statusText }));
    throw new Error(body.error || res.statusText);
  }

  return res.json();
}

// Auth
export const auth = {
  status: () => request<{ hasPassword: boolean }>('/auth/status'),
  login: (password: string) => request<{ ok: boolean }>('/auth/login', {
    method: 'POST',
    body: JSON.stringify({ password }),
  }),
};

// Subscriptions
export const subscriptions = {
  list: () => request<any[]>('/subscriptions'),
  create: (name: string, url: string) => request<{ id: number }>('/subscriptions', {
    method: 'POST',
    body: JSON.stringify({ name, url }),
  }),
  update: (id: number, data: any) => request<{ ok: boolean }>(`/subscriptions/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  }),
  delete: (id: number) => request<{ ok: boolean }>(`/subscriptions/${id}`, {
    method: 'DELETE',
  }),
  fetch: (id: number) => request<{ nodeCount: number }>(`/subscriptions/${id}/fetch`, {
    method: 'POST',
  }),
  nodes: (id: number) => request<any[]>(`/subscriptions/${id}/nodes`),
};

// Nodes
export const nodes = {
  fetchedToggle: (id: number, enabled: boolean) => request<{ ok: boolean }>(`/nodes/fetched/${id}`, {
    method: 'PUT',
    body: JSON.stringify({ enabled }),
  }),
  fetchedBatch: (ids: number[], enabled: boolean) => request<{ ok: boolean }>('/nodes/fetched/batch', {
    method: 'PUT',
    body: JSON.stringify({ ids, enabled }),
  }),
  staticList: () => request<any[]>('/nodes/static'),
  staticCreate: (uri: string, name?: string) => request<any>('/nodes/static', {
    method: 'POST',
    body: JSON.stringify({ uri, name }),
  }),
  staticUpdate: (id: number, data: any) => request<{ ok: boolean }>(`/nodes/static/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  }),
  staticDelete: (id: number) => request<{ ok: boolean }>(`/nodes/static/${id}`, {
    method: 'DELETE',
  }),
};

// Rules
export const rules = {
  list: () => request<any[]>('/rules'),
  create: (data: any) => request<{ id: number }>('/rules', {
    method: 'POST',
    body: JSON.stringify(data),
  }),
  update: (id: number, data: any) => request<{ ok: boolean }>(`/rules/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  }),
  delete: (id: number) => request<{ ok: boolean }>(`/rules/${id}`, {
    method: 'DELETE',
  }),
  reorder: (ids: number[]) => request<{ ok: boolean }>('/rules/reorder', {
    method: 'PUT',
    body: JSON.stringify({ ids }),
  }),
};

// Config
export const config = {
  preview: () => request<{ config: string }>('/config/preview'),
};

// Stats
export const stats = {
  get: () => request<any>('/stats'),
};
