import api, { ApiResponse } from './api';

// Types
export interface TwoFactorSetupResponse {
  secret: string;
  qrCode: string;
  manualEntry: string;
}

export interface TwoFactorEnableResponse {
  backupCodes: string[];
}

export interface TwoFactorStatusResponse {
  enabled: boolean;
  verifiedAt: string | null;
}

export interface TwoFactorLoginRequest {
  tempToken: string;
  token: string;
  userAgent?: string;
  ipAddress?: string;
}

export interface TwoFactorBackupCodeRequest {
  tempToken: string;
  backupCode: string;
  userAgent?: string;
  ipAddress?: string;
}

export interface TwoFactorLoginResponse {
  user: {
    id: string;
    email: string;
    role: string;
    firstName?: string;
    lastName?: string;
    avatar?: string;
  };
  accessToken: string;
  refreshToken: string;
}

export interface TwoFactorRequiredResponse {
  requiresTwoFactor: true;
  tempToken: string;
  user: {
    id: string;
    email: string;
  };
}

// Two-Factor Service
class TwoFactorService {
  private basePath = '/auth/2fa';

  /**
   * Setup 2FA - generates secret and QR code
   */
  async setup(): Promise<ApiResponse<TwoFactorSetupResponse>> {
    const response = await api.post<ApiResponse<TwoFactorSetupResponse>>(
      `${this.basePath}/setup`
    );
    return response.data;
  }

  /**
   * Enable 2FA - verify token and enable
   */
  async enable(token: string): Promise<ApiResponse<TwoFactorEnableResponse>> {
    const response = await api.post<ApiResponse<TwoFactorEnableResponse>>(
      `${this.basePath}/enable`,
      { token }
    );
    return response.data;
  }

  /**
   * Disable 2FA - requires password confirmation
   */
  async disable(password: string): Promise<ApiResponse<{ message: string }>> {
    const response = await api.post<ApiResponse<{ message: string }>>(
      `${this.basePath}/disable`,
      { password }
    );
    return response.data;
  }

  /**
   * Verify 2FA token during login
   */
  async verifyLogin(data: TwoFactorLoginRequest): Promise<ApiResponse<TwoFactorLoginResponse>> {
    const response = await api.post<ApiResponse<TwoFactorLoginResponse>>(
      `${this.basePath}/verify`,
      data
    );
    return response.data;
  }

  /**
   * Verify backup code during login
   */
  async verifyBackupCode(data: TwoFactorBackupCodeRequest): Promise<ApiResponse<TwoFactorLoginResponse>> {
    const response = await api.post<ApiResponse<TwoFactorLoginResponse>>(
      `${this.basePath}/verify-backup`,
      data
    );
    return response.data;
  }

  /**
   * Get 2FA status
   */
  async getStatus(): Promise<ApiResponse<TwoFactorStatusResponse>> {
    const response = await api.get<ApiResponse<TwoFactorStatusResponse>>(
      `${this.basePath}/status`
    );
    return response.data;
  }

  /**
   * Regenerate backup codes - requires password confirmation
   */
  async regenerateBackupCodes(password: string): Promise<ApiResponse<TwoFactorEnableResponse>> {
    const response = await api.post<ApiResponse<TwoFactorEnableResponse>>(
      `${this.basePath}/backup-codes`,
      { password }
    );
    return response.data;
  }

  /**
   * Check if response indicates 2FA is required
   */
  static isTwoFactorRequired(response: unknown): response is TwoFactorRequiredResponse {
    return (
      typeof response === 'object' &&
      response !== null &&
      'requiresTwoFactor' in response &&
      (response as TwoFactorRequiredResponse).requiresTwoFactor === true
    );
  }
}

export const twoFactorService = new TwoFactorService();
export { TwoFactorService };
