const API_BASE = '/api'

// Global callback for 401 responses (set by app component to trigger auto-logout)
let onUnauthorized = null

export function setOnUnauthorized(callback) {
  onUnauthorized = callback
}

function getToken() {
  return localStorage.getItem('token')
}

function authHeaders() {
  const token = getToken()
  return token ? { Authorization: `Bearer ${token}` } : {}
}

async function request(method, path, body) {
  const opts = {
    method,
    headers: {
      'Content-Type': 'application/json',
      ...authHeaders(),
    },
  }

  if (body) {
    opts.body = JSON.stringify(body)
  }

  const res = await fetch(`${API_BASE}${path}`, opts)

  if (!res.ok) {
    // Auto-logout on 401 for any authenticated request (not login/register)
    if (res.status === 401 && path !== '/auth/login' && path !== '/auth/register' && path !== '/auth/nostr/verify') {
      if (onUnauthorized) onUnauthorized()
      throw new Error('Session expired — please log in again')
    }
    const text = await res.text()
    const err = new Error(text || `HTTP ${res.status}`)
    err.status = res.status
    throw err
  }

  if (res.status === 204 || res.headers.get('content-length') === '0') {
    return null
  }

  return res.json()
}

export const api = {
  // Auth
  register: (data) => request('POST', '/auth/register', data),
  login: (data) => request('POST', '/auth/login', data),
  me: () => request('GET', '/auth/me'),

  // Profile
  updateProfile: (data) => request('PUT', '/auth/profile', data),
  uploadAvatar: async (file) => {
    const formData = new FormData()
    formData.append('avatar', file)
    const res = await fetch(`${API_BASE}/auth/avatar`, {
      method: 'POST',
      headers: authHeaders(),
      body: formData,
    })
    if (!res.ok) {
      const text = await res.text()
      throw new Error(text || `HTTP ${res.status}`)
    }
    return res.json()
  },
  deleteAvatar: () => request('DELETE', '/auth/avatar'),

  // Rooms
  listRooms: () => request('GET', '/rooms'),
  createRoom: (data) => request('POST', '/rooms', data),
  getRoom: (roomId) => request('GET', `/rooms/${roomId}`),
  getMessages: (roomId, limit = 50, before) => {
    const params = new URLSearchParams({ limit: String(limit) })
    if (before) params.set('before', before)
    return request('GET', `/rooms/${roomId}/messages?${params}`)
  },
  joinRoom: (roomId) => request('POST', `/rooms/${roomId}/join`),
  deleteRoom: (roomId) => request('DELETE', `/rooms/${roomId}`),
  clearRoom: (roomId) => request('POST', `/rooms/${roomId}/clear`),
  resolveMessageHash: (hash) => request('GET', `/messages/hash/${hash}`),

  // Models
  listModels: () => request('GET', '/models'),

  // Upload (chat images)
  uploadChatImage: async (file) => {
    const formData = new FormData()
    formData.append('image', file)
    const res = await fetch(`${API_BASE}/upload`, {
      method: 'POST',
      headers: authHeaders(),
      body: formData,
    })
    if (!res.ok) {
      const text = await res.text()
      throw new Error(text || `HTTP ${res.status}`)
    }
    return res.json()
  },

  // Invites
  createInvite: (data) => request('POST', '/invites', data),
  acceptInvite: (token) => request('POST', `/invites/${token}/accept`),
  inviteByNostr: (data) => request('POST', '/invites/nostr', data),

  // Nostr auth
  nostrChallenge: () => request('GET', '/auth/nostr/challenge'),
  nostrVerify: (data) => request('POST', '/auth/nostr/verify', data),
}

export function saveAuth(token, user) {
  localStorage.setItem('token', token)
  localStorage.setItem('user', JSON.stringify(user))
}

export function getUser() {
  const raw = localStorage.getItem('user')
  return raw ? JSON.parse(raw) : null
}

export function clearAuth() {
  localStorage.removeItem('token')
  localStorage.removeItem('user')
}

export function isAuthenticated() {
  return !!getToken()
}
