/**
 * Authentication API client for the dashboard.
 * 
 * Provides functions to interact with auth endpoints including login,
 * logout, and fetching current user information.
 */

export interface User {
  id: number;
  username: string;
  role: 'user' | 'editor' | 'admin' | 'superadmin';
  is_active: boolean;
}

export interface LoginRequest {
  username: string;
  password: string;
}

export interface LoginResponse {
  message: string;
  user: {
    id: number;
    username: string;
    role: string;
  };
}

export interface AuthCheckResponse {
  authenticated: boolean;
  role?: string;
}

/**
 * Change password for the currently authenticated user.
 */
export async function changePassword(currentPassword: string, newPassword: string): Promise<{ message: string }> {
  const res = await fetch('/api/auth/change-password', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ current_password: currentPassword, new_password: newPassword }),
  });

  const data = await res.json();

  if (!res.ok) {
    throw new Error(data.error || 'Failed to change password');
  }

  return data as { message: string };
}

/**
 * Authenticate a user with username and password.
 * 
 * @param username - The user's username
 * @param password - The user's password
 * @returns Promise<LoginResponse>
 * @throws Error if login fails
 */
export async function login(username: string, password: string): Promise<LoginResponse> {
  const res = await fetch('/api/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include', // Important for session cookies
    body: JSON.stringify({ username, password }),
  });
  
  const data = await res.json();
  
  if (!res.ok || data.error) {
    throw new Error(data.error || 'Login failed');
  }
  
  return data;
}

/**
 * Log out the current user.
 * 
 * @returns Promise<void>
 * @throws Error if logout fails
 */
export async function logout(): Promise<void> {
  const res = await fetch('/api/auth/logout', {
    method: 'POST',
    credentials: 'include',
  });
  
  const data = await res.json();
  
  if (!res.ok || data.error) {
    throw new Error(data.error || 'Logout failed');
  }
}

/**
 * Fetch the current authenticated user's information.
 * 
 * @returns Promise<User>
 * @throws Error if not authenticated or request fails
 */
export async function fetchCurrentUser(): Promise<User> {
  const res = await fetch('/api/auth/me', {
    method: 'GET',
    credentials: 'include',
  });
  
  const data = await res.json();
  
  if (!res.ok || data.error) {
    throw new Error(data.error || 'Failed to fetch current user');
  }
  
  return data as User;
}

/**
 * Quick check if user is authenticated (lighter than fetchCurrentUser).
 * 
 * @returns Promise<AuthCheckResponse>
 */
export async function checkAuth(): Promise<AuthCheckResponse> {
  const res = await fetch('/api/auth/check', {
    method: 'GET',
    credentials: 'include',
  });
  
  const data = await res.json();
  
  if (!res.ok) {
    throw new Error('Failed to check authentication status');
  }
  
  return data;
}

/**
 * Helper function to check if a user has a specific role.
 * 
 * @param user - The user object
 * @param role - The role to check for
 * @returns boolean
 */
export function hasRole(user: User | null, role: string): boolean {
  if (!user) return false;
  return user.role === role;
}

/**
 * Helper function to check if a user has any of the specified roles.
 * 
 * @param user - The user object
 * @param roles - Array of roles to check for
 * @returns boolean
 */
export function hasAnyRole(user: User | null, roles: string[]): boolean {
  if (!user) return false;
  return roles.includes(user.role);
}

/**
 * Helper function to check if user is superadmin.
 */
export function isSuperadmin(user: User | null): boolean {
  return hasRole(user, 'superadmin');
}

/**
 * Helper function to check if user is admin or higher.
 */
export function isAdminOrHigher(user: User | null): boolean {
  return hasAnyRole(user, ['admin', 'superadmin']);
}

/**
 * Helper function to check if user is editor or higher.
 */
export function isEditorOrHigher(user: User | null): boolean {
  return hasAnyRole(user, ['editor', 'admin', 'superadmin']);
}
