import { LoginDto, RegisterDto, AuthResponse, ApiResponse, UserResponse } from '@goodgo/types';

import { apiClient } from './client';

/**
 * EN: Authentication API service for frontend
 * VI: Service API xác thực cho frontend
 */
export const authApi = {
  /**
   * EN: Register new user account
   * VI: Đăng ký tài khoản người dùng mới
   */
  register: async (data: RegisterDto): Promise<ApiResponse<AuthResponse>> => {
    return apiClient.post('/auth/register', data);
  },

  /**
   * EN: Login user and store tokens
   * VI: Đăng nhập người dùng và lưu tokens
   */
  login: async (data: LoginDto): Promise<ApiResponse<AuthResponse>> => {
    const response = await apiClient.post('/auth/login', data);
    // EN: Store tokens in client and localStorage on successful login
    // VI: Lưu tokens trong client và localStorage khi đăng nhập thành công
    if (response.success && response.data) {
      apiClient.setAuthToken(response.data.accessToken);
      if (typeof window !== 'undefined') {
        localStorage.setItem('refreshToken', response.data.refreshToken);
      }
    }
    return response;
  },

  /**
   * EN: Logout user and clear tokens
   * VI: Đăng xuất người dùng và xóa tokens
   */
  logout: async (): Promise<ApiResponse> => {
    // EN: Get refresh token from localStorage for logout request
    // VI: Lấy refresh token từ localStorage cho request logout
    const refreshToken = typeof window !== 'undefined' ? localStorage.getItem('refreshToken') : null;
    const response = await apiClient.post('/auth/logout', { refreshToken });
    // EN: Clear tokens from client and localStorage
    // VI: Xóa tokens khỏi client và localStorage
    apiClient.removeAuthToken();
    if (typeof window !== 'undefined') {
      localStorage.removeItem('refreshToken');
    }
    return response;
  },

  /**
   * EN: Refresh access token using refresh token
   * VI: Làm mới access token sử dụng refresh token
   */
  refreshToken: async (refreshToken: string): Promise<ApiResponse<{ accessToken: string }>> => {
    const response = await apiClient.post('/auth/refresh', { refreshToken });
    // EN: Update access token in client on successful refresh
    // VI: Cập nhật access token trong client khi refresh thành công
    if (response.success && response.data) {
      apiClient.setAuthToken(response.data.accessToken);
    }
    return response;
  },

  /**
   * EN: Get current authenticated user profile
   * VI: Lấy hồ sơ người dùng đã xác thực hiện tại
   */
  getMe: async (): Promise<ApiResponse<UserResponse>> => {
    return apiClient.get('/identity/profile');
  },

  /**
   * EN: Change user password
   * VI: Thay đổi mật khẩu người dùng
   */
  changePassword: async (currentPassword: string, newPassword: string): Promise<ApiResponse> => {
    return apiClient.post('/auth/change-password', { currentPassword, newPassword });
  },

  /**
   * EN: Request password reset link via email
   * VI: Yêu cầu link đặt lại mật khẩu qua email
   */
  forgotPassword: async (email: string): Promise<ApiResponse> => {
    return apiClient.post('/auth/forgot-password', { email });
  },

  /**
   * EN: Reset password using reset token
   * VI: Đặt lại mật khẩu sử dụng reset token
   */
  resetPassword: async (token: string, newPassword: string): Promise<ApiResponse> => {
    return apiClient.post('/auth/reset-password', { token, newPassword });
  },

  /**
   * EN: Authenticate with OAuth token from callback
   * VI: Xác thực với OAuth token từ callback
   */
  oauthLogin: async (accessToken: string): Promise<ApiResponse<AuthResponse>> => {
    // EN: Set the token in the client
    // VI: Đặt token trong client
    apiClient.setAuthToken(accessToken);

    // EN: Fetch user profile to complete authentication
    // VI: Lấy thông tin user để hoàn tất xác thực
    const userResponse = await apiClient.get('/identity/profile');

    if (userResponse.success && userResponse.data) {
      // EN: Store refresh token if available (OAuth might not provide refresh token)
      // VI: Lưu refresh token nếu có (OAuth có thể không cung cấp refresh token)
      // Note: For OAuth, we only have access token, refresh token handling depends on backend
      // Ghi chú: Đối với OAuth, chúng ta chỉ có access token, xử lý refresh token phụ thuộc vào backend

      return {
        success: true,
        data: {
          accessToken,
          refreshToken: '', // EN: OAuth may not provide refresh token / VI: OAuth có thể không cung cấp refresh token
          user: userResponse.data,
        },
        timestamp: new Date().toISOString(),
      };
    }

    throw new Error('Failed to fetch user profile / Không thể lấy thông tin người dùng');
  },

  /**
   * EN: Enable TOTP and get QR code
   * VI: Bật TOTP và lấy mã QR
   */
  enableTOTP: async (): Promise<ApiResponse<{ secret: string; qrCodeUrl: string }>> => {
    return apiClient.post('/mfa/totp/enable', {});
  },

  /**
   * EN: Verify and enable TOTP with token
   * VI: Xác thực và bật TOTP với token
   */
  verifyAndEnableTOTP: async (secret: string, token: string): Promise<ApiResponse> => {
    return apiClient.post('/mfa/totp/verify', { secret, token });
  },

  /**
   * EN: Disable MFA
   * VI: Tắt MFA
   */
  disableMFA: async (): Promise<ApiResponse> => {
    return apiClient.post('/mfa/disable', {});
  },

  /**
   * EN: Get MFA devices
   * VI: Lấy thiết bị MFA
   */
  getMFADevices: async (): Promise<ApiResponse<Array<{ id: string; type: string; name: string; lastUsedAt: string | null; createdAt: string }>>> => {
    return apiClient.get('/mfa/devices');
  },

  /**
   * EN: Get user sessions
   * VI: Lấy sessions của người dùng
   */
  getSessions: async (): Promise<ApiResponse<Array<{ id: string; deviceName: string | null; ipAddress: string | null; lastActivityAt: string | null; createdAt: string; expiresAt: string | null }>>> => {
    return apiClient.get('/sessions');
  },

  /**
   * EN: Revoke a session
   * VI: Thu hồi một session
   */
  revokeSession: async (sessionId: string): Promise<ApiResponse> => {
    return apiClient.delete(`/sessions/${sessionId}`);
  },

  /**
   * EN: Revoke all sessions
   * VI: Thu hồi tất cả sessions
   */
  revokeAllSessions: async (): Promise<ApiResponse> => {
    return apiClient.delete('/sessions');
  },
};
