/**
 * Authentication API Client
 *
 * Provides login, register, and user info API calls
 */

import { api } from './apiClient';

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

export interface RegisterRequest {
  username: string;
  email: string;
  password: string;
}

export interface User {
  id: string;
  username: string;
  email: string;
  avatarUrl?: string;
  isActive: boolean;
  isSuperuser: boolean;
  permissions?: string[];
  roles?: string[];
}

export interface SessionInfo {
  id: string;
  sessionFamilyId?: string;
  status: string;
  deviceName?: string;
  ipAddress?: string;
  userAgent?: string;
  createdAt: number;
  updatedAt: number;
  expiresAt: number;
  lastUsedAt?: number | null;
  revokedAt?: number | null;
  revokedReason?: string | null;
  current: boolean;
}

export interface AuthResponse {
  accessToken: string;
  refreshToken: string;
  tokenType: string;
  expiresIn: number;
  sessionId?: string;
  user: User;
}

export interface SessionResponse {
  authenticated: boolean;
  sessionId?: string | null;
  user: User;
  session?: SessionInfo | null;
}

/** Backend 统一包装格式 BaseResponse */
interface ApiResponse<T> {
  code?: string;
  message?: string;
  data?: T;
}

/**
 * Login with username/email and password
 */
export async function login(request: LoginRequest): Promise<AuthResponse> {
  const response = await api.post<ApiResponse<AuthResponse>>('/api/v1/auth/login', request);
  const payload = response.data?.data ?? response.data;
  if (!payload || typeof payload !== 'object' || !('accessToken' in payload)) {
    throw new Error('Invalid login response');
  }
  return payload as AuthResponse;
}

/**
 * Register a new user
 */
export async function register(request: RegisterRequest): Promise<AuthResponse> {
  const response = await api.post<ApiResponse<AuthResponse>>('/api/v1/auth/register', request);
  const payload = response.data?.data ?? response.data;
  if (!payload || typeof payload !== 'object' || !('accessToken' in payload)) {
    throw new Error('Invalid register response');
  }
  return payload as AuthResponse;
}

/**
 * Get current user info
 */
export async function getCurrentUser(): Promise<User> {
  const response = await api.get<ApiResponse<{ id: string; username: string; email: string; avatarUrl?: string; isActive: boolean; isSuperuser: boolean; permissions?: string[]; roles?: string[] }>>('/api/v1/auth/me');
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') throw new Error('Invalid user response');
  const userData = data as { id: string; username: string; email: string; avatarUrl?: string; isActive: boolean; isSuperuser: boolean; permissions?: string[]; roles?: string[] };
  return {
    id: userData.id,
    username: userData.username,
    email: userData.email,
    avatarUrl: userData.avatarUrl,
    isActive: userData.isActive,
    isSuperuser: userData.isSuperuser,
    permissions: userData.permissions,
    roles: userData.roles,
  };
}

/**
 * Get current authenticated session info
 */
export async function getCurrentSession(): Promise<SessionResponse> {
  const response = await api.get<ApiResponse<SessionResponse>>('/api/v1/auth/session');
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') {
    throw new Error('Invalid session response');
  }
  return data as SessionResponse;
}

/**
 * List user sessions
 */
export async function listSessions(includeInactive = false): Promise<{ items: SessionInfo[]; total: number }> {
  const response = await api.get<ApiResponse<{ items: SessionInfo[]; total: number }>>('/api/v1/auth/sessions', {
    params: { includeInactive },
  });
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object' || !('items' in data)) {
    throw new Error('Invalid sessions response');
  }
  return data as { items: SessionInfo[]; total: number };
}

/**
 * Revoke a specific session
 */
export async function revokeSession(sessionId: string): Promise<{ sessionId: string; revoked: boolean; current: boolean; revokedAccess: boolean }> {
  const response = await api.delete<ApiResponse<{ sessionId: string; revoked: boolean; current: boolean; revokedAccess: boolean }>>(`/api/v1/auth/sessions/${sessionId}`);
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') {
    throw new Error('Invalid revoke session response');
  }
  return data as { sessionId: string; revoked: boolean; current: boolean; revokedAccess: boolean };
}

/**
 * Logout
 */
export async function logout(refreshToken?: string): Promise<void> {
  await api.post('/api/v1/auth/logout', { refreshToken: refreshToken ?? '' });
}

/**
 * Refresh access token
 */
export async function refreshToken(refreshToken: string): Promise<AuthResponse> {
  const response = await api.post<ApiResponse<AuthResponse>>('/api/v1/auth/refresh', { refreshToken });
  const payload = response.data?.data ?? response.data;
  if (!payload || typeof payload !== 'object' || !('accessToken' in payload)) {
    throw new Error('Invalid refresh response');
  }
  return payload as AuthResponse;
}

/**
 * Upload user avatar
 */
export async function uploadAvatar(file: File): Promise<{ avatarUrl: string; user: User }> {
  const formData = new FormData();
  formData.append('file', file);

  const response = await api.post<ApiResponse<{ avatarUrl: string; user: User }>>('/api/v1/auth/avatar', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  });
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') throw new Error('Invalid avatar upload response');
  return data as { avatarUrl: string; user: User };
}

/**
 * Request password reset
 */
export async function forgotPassword(email: string): Promise<{ resetToken?: string; expiresIn: number }> {
  const response = await api.post<ApiResponse<{ resetToken?: string; expiresIn: number }>>('/api/v1/auth/forgot-password', { email });
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') throw new Error('Invalid forgot password response');
  return data as { resetToken?: string; expiresIn: number };
}

/**
 * Verify reset token
 */
export async function verifyResetToken(token: string): Promise<{ valid: boolean; email?: string }> {
  const response = await api.post<ApiResponse<{ valid: boolean; email?: string }>>('/api/v1/auth/verify-reset-token', { token });
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') throw new Error('Invalid verify token response');
  return data as { valid: boolean; email?: string };
}

/**
 * Reset password with token
 */
export async function resetPassword(token: string, newPassword: string): Promise<{ userId: string; email: string }> {
  const response = await api.post<ApiResponse<{ userId: string; email: string }>>('/api/v1/auth/reset-password', {
    token,
    newPassword,
  });
  const data = response.data?.data ?? response.data;
  if (!data || typeof data !== 'object') throw new Error('Invalid reset password response');
  return data as { userId: string; email: string };
}
