/**
 * API Service Layer
 * Handles all communication with the backend API
 */

const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8001/api'

type ApiOptions = {
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
  body?: unknown
  token?: string | null
}

async function apiCall<T>(
  endpoint: string,
  options: ApiOptions = {}
): Promise<T> {
  const { method = 'GET', body, token } = options

  const headers: HeadersInit = {
    'Content-Type': 'application/json',
  }

  if (token) {
    headers['Authorization'] = `Bearer ${token}`
  }

  const config: RequestInit = {
    method,
    headers,
    credentials: 'include',
  }

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

  const response = await fetch(`${API_BASE_URL}${endpoint}`, config)

  if (!response.ok) {
    const error = await response.json().catch(() => ({}))
    throw new Error(error.detail || `API error: ${response.statusText}`)
  }

  return response.json() as Promise<T>
}

// ============================================
// USER ENDPOINTS
// ============================================

export async function registerUser(
  userData: {
    email: string
    displayName?: string
    photoURL?: string
  },
  token: string
) {
  return apiCall('/users/register', {
    method: 'POST',
    body: userData,
    token,
  })
}

export async function getUserByEmail(email: string, token: string) {
  return apiCall(`/users/by-email/${email}`, { token })
}

export async function updateUserProfile(
  userId: string,
  updates: { displayName?: string; photoURL?: string; theme?: string; tutorial?: boolean; backgroundImage?: string | null; backgroundImages?: string[] },
  token: string
) {
  return apiCall(`/users/${userId}`, {
    method: 'PUT',
    body: updates,
    token,
  })
}

export async function deleteUser(userId: string, token: string) {
  return apiCall<{ message: string; user_deleted: number; entries_deleted: number }>(
    `/users/${userId}`,
    {
      method: 'DELETE',
      token,
    }
  )
}

// ============================================
// ENTRY ENDPOINTS
// ============================================

export interface EncryptionMetadata {
  encrypted: boolean
  ciphertext?: string  // Base64-encoded encrypted content
  nonce?: string  // Base64-encoded nonce
  algorithm?: string  // e.g., "XSalsa20-Poly1305"
}

export interface JournalEntryCreate {
  title?: string  // Optional if encrypted
  content?: string  // Optional if encrypted
  mood?: string
  tags?: string[]
  isPublic?: boolean
  encryption?: EncryptionMetadata
}

export interface JournalEntry extends JournalEntryCreate {
  id: string
  userId: string
  createdAt: string
  updatedAt: string
  entryDate?: string
  encryption?: EncryptionMetadata
}

export async function createEntry(
  userId: string,
  entryData: JournalEntryCreate,
  token: string
) {
  return apiCall<{ id: string; message: string }>(
    `/entries/${userId}`,
    {
      method: 'POST',
      body: entryData,
      token,
    }
  )
}

export async function getUserEntries(
  userId: string,
  token: string,
  limit = 50,
  skip = 0
) {
  return apiCall<{ entries: JournalEntry[]; total: number }>(
    `/entries/${userId}?limit=${limit}&skip=${skip}`,
    { token }
  )
}

export async function getEntry(
  userId: string,
  entryId: string,
  token: string
) {
  return apiCall<JournalEntry>(`/entries/${userId}/${entryId}`, {
    token,
  })
}

export async function updateEntry(
  userId: string,
  entryId: string,
  updates: Partial<JournalEntryCreate>,
  token: string
) {
  return apiCall(`/entries/${userId}/${entryId}`, {
    method: 'PUT',
    body: updates,
    token,
  })
}

export async function deleteEntry(
  userId: string,
  entryId: string,
  token: string
) {
  return apiCall(`/entries/${userId}/${entryId}`, {
    method: 'DELETE',
    token,
  })
}

export async function getEntriesByDate(
  userId: string,
  startDate: string,
  endDate: string,
  token: string
) {
  return apiCall<JournalEntry[]>(
    `/entries/${userId}/date-range?startDate=${startDate}&endDate=${endDate}`,
    { token }
  )
}
// ============================================
// TIMEZONE CONVERSION ENDPOINTS
// ============================================

export async function convertUTCToIST(utcTimestamp: string) {
  return apiCall<{ utc: string; ist: string }>(
    `/entries/convert-timestamp/utc-to-ist`,
    {
      method: 'POST',
      body: { timestamp: utcTimestamp },
    }
  )
}