// ---------------------------------------------------------------------------
// Auth API client  (client-side)
// ---------------------------------------------------------------------------
// Login & logout go through dedicated Next.js route handlers that manage the
// httpOnly cookie. All other auth routes use the catch-all proxy.
// ---------------------------------------------------------------------------

import { ApiError } from './client';

// ---------------------------------------------------------------------------
// Request / response shapes (inline; will unify with @/lib/types later)
// TODO: import from @/lib/types once the shared types package is finalised
// ---------------------------------------------------------------------------

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

/** Login response after the route handler strips the raw token. */
export interface LoginResponse {
  user: UserResponse;
}

export interface RegisterRequest {
  username: string;
  email: string;
  password: string;
  first_name?: string;
  last_name?: string;
}

export interface RegisterResponse {
  token: string;
  user: UserResponse;
}

export interface UserResponse {
  id: number;
  username: string;
  email: string;
  first_name: string;
  last_name: string;
  is_email_verified: boolean;
  profile_image_url?: string;
  date_joined: string;
}

export interface UpdateProfileRequest {
  email?: string;
  first_name?: string;
  last_name?: string;
}

export interface ForgotPasswordRequest {
  email: string;
}

export interface VerifyResetCodeRequest {
  email: string;
  code: string;
}

export interface VerifyResetCodeResponse {
  message: string;
  reset_token: string;
}

export interface ResetPasswordRequest {
  reset_token: string;
  new_password: string;
}

export interface VerifyEmailRequest {
  code: string;
}

export interface VerifyEmailResponse {
  message: string;
  verified: boolean;
}

export interface MessageResponse {
  message: string;
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

async function handleResponse<T>(res: Response): Promise<T> {
  const body = await res.json().catch(() => ({ error: 'Unknown error' }));
  if (!res.ok) {
    throw new ApiError(
      res.status,
      body.message || body.error || 'Request failed',
      body.details,
    );
  }
  return body as T;
}

function timezone(): string {
  return Intl.DateTimeFormat().resolvedOptions().timeZone;
}

// ---------------------------------------------------------------------------
// Public API functions
// ---------------------------------------------------------------------------

/**
 * Log in with username/email + password.
 * Uses the dedicated `/api/auth/login` route handler which sets the httpOnly
 * cookie and strips the token from the response.
 */
export async function login(credentials: LoginRequest): Promise<LoginResponse> {
  const res = await fetch('/api/auth/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(credentials),
  });
  return handleResponse<LoginResponse>(res);
}

/**
 * Register a new account.
 * Goes through the proxy; the token is returned in the response body
 * (caller should follow up with `login` to set the cookie).
 */
export async function register(
  data: RegisterRequest,
): Promise<RegisterResponse> {
  const res = await fetch('/api/proxy/auth/register', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<RegisterResponse>(res);
}

/**
 * Log out. Clears the httpOnly cookie and invalidates the token server-side.
 */
export async function logout(): Promise<MessageResponse> {
  const res = await fetch('/api/auth/logout', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
  });
  return handleResponse<MessageResponse>(res);
}

/**
 * Get the currently authenticated user.
 */
export async function getCurrentUser(): Promise<UserResponse> {
  const res = await fetch('/api/auth/me', {
    headers: { 'Content-Type': 'application/json' },
  });
  return handleResponse<UserResponse>(res);
}

/**
 * Update the authenticated user's profile.
 */
export async function updateProfile(
  data: UpdateProfileRequest,
): Promise<UserResponse> {
  const res = await fetch('/api/proxy/auth/profile', {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<UserResponse>(res);
}

/**
 * Verify the user's email with a 6-digit code.
 */
export async function verifyEmail(
  data: VerifyEmailRequest,
): Promise<VerifyEmailResponse> {
  const res = await fetch('/api/proxy/auth/verify-email', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<VerifyEmailResponse>(res);
}

/**
 * Resend the email verification code.
 */
export async function resendVerification(): Promise<MessageResponse> {
  const res = await fetch('/api/proxy/auth/resend-verification', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
  });
  return handleResponse<MessageResponse>(res);
}

/**
 * Request a password reset email.
 */
export async function forgotPassword(
  data: ForgotPasswordRequest,
): Promise<MessageResponse> {
  const res = await fetch('/api/proxy/auth/forgot-password', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<MessageResponse>(res);
}

/**
 * Verify the 6-digit reset code; returns a reset token.
 */
export async function verifyResetCode(
  data: VerifyResetCodeRequest,
): Promise<VerifyResetCodeResponse> {
  const res = await fetch('/api/proxy/auth/verify-reset-code', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<VerifyResetCodeResponse>(res);
}

/**
 * Reset password using the token from `verifyResetCode`.
 */
export async function resetPassword(
  data: ResetPasswordRequest,
): Promise<MessageResponse> {
  const res = await fetch('/api/proxy/auth/reset-password', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<MessageResponse>(res);
}

/**
 * Change the authenticated user's password.
 */
export async function changePassword(
  data: { current_password: string; new_password: string },
): Promise<MessageResponse> {
  const res = await fetch('/api/proxy/auth/change-password', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
    body: JSON.stringify(data),
  });
  return handleResponse<MessageResponse>(res);
}

/**
 * Delete the authenticated user's account permanently.
 */
export async function deleteAccount(): Promise<MessageResponse> {
  const res = await fetch('/api/proxy/auth/delete-account', {
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json',
      'X-Timezone': timezone(),
    },
  });
  return handleResponse<MessageResponse>(res);
}
