/**
 * Authentication Service Interfaces
 * Abstraction for authentication operations following DIP
 */

import type {
  User,
  Profile,
  AuthTokens,
  AuthResponse,
  Session,
  JWTPayload,
  JWTRefreshPayload,
  RegisterEmailRequest,
  LoginEmailRequest,
} from '../../../modules/auth/types/auth.types';

/**
 * Token Service Interface
 */
export interface ITokenService {
  /**
   * Generate access token for a user
   */
  generateAccessToken(user: User): string;

  /**
   * Generate refresh token for a session
   */
  generateRefreshToken(userId: string, sessionId: string): string;

  /**
   * Verify access token and return payload
   */
  verifyAccessToken(token: string): JWTPayload | null;

  /**
   * Verify refresh token and return payload
   */
  verifyRefreshToken(token: string): JWTRefreshPayload | null;

  /**
   * Create a new session with tokens
   */
  createSession(
    userId: string,
    userAgent?: string,
    ipAddress?: string,
    deviceInfo?: Record<string, unknown>
  ): Promise<{ session: Session; tokens: AuthTokens }>;

  /**
   * Refresh an existing session
   */
  refreshSession(refreshToken: string): Promise<AuthTokens | null>;

  /**
   * Revoke a specific session
   */
  revokeSession(sessionId: string, userId: string): Promise<boolean>;

  /**
   * Revoke all user sessions except one
   */
  revokeAllUserSessions(userId: string, exceptSessionId?: string): Promise<number>;

  /**
   * Get active sessions for a user
   */
  getActiveSessions(userId: string): Promise<Session[]>;

  /**
   * Generate email verification token
   */
  generateEmailToken(): string;

  /**
   * Hash a token
   */
  hashToken(token: string): string;
}

/**
 * Email Authentication Service Interface
 */
export interface IEmailService {
  /**
   * Register a new user with email/password
   */
  register(
    data: RegisterEmailRequest,
    userAgent?: string,
    ipAddress?: string
  ): Promise<{ userId: string; message: string }>;

  /**
   * Login with email/password
   */
  login(
    data: LoginEmailRequest,
    userAgent?: string,
    ipAddress?: string
  ): Promise<AuthResponse>;

  /**
   * Send email verification
   */
  sendVerificationEmail(userId: string, email: string): Promise<void>;

  /**
   * Verify email with token
   */
  verifyEmail(token: string): Promise<{ success: boolean; message: string }>;

  /**
   * Send password reset email
   */
  sendPasswordResetEmail(email: string): Promise<{ message: string }>;

  /**
   * Reset password with token
   */
  resetPassword(token: string, newPassword: string): Promise<{ message: string }>;

  /**
   * Change password for authenticated user
   */
  changePassword(
    userId: string,
    currentPassword: string,
    newPassword: string
  ): Promise<{ message: string }>;
}

/**
 * OAuth Service Interface
 */
export interface IOAuthService {
  /**
   * Generate OAuth authorization URL
   */
  getAuthorizationUrl(provider: string, state: string): string;

  /**
   * Handle OAuth callback
   */
  handleCallback(
    provider: string,
    code: string,
    state: string,
    userAgent?: string,
    ipAddress?: string
  ): Promise<AuthResponse>;
}

/**
 * Two-Factor Authentication Service Interface
 */
export interface ITwoFactorService {
  /**
   * Generate TOTP secret
   */
  generateTOTPSecret(userId: string): Promise<{ secret: string; qrCode: string }>;

  /**
   * Enable TOTP for user
   */
  enableTOTP(userId: string, code: string): Promise<{ success: boolean; backupCodes: string[] }>;

  /**
   * Disable TOTP for user
   */
  disableTOTP(userId: string, password: string): Promise<{ success: boolean }>;

  /**
   * Verify TOTP code
   */
  verifyTOTP(userId: string, code: string): Promise<boolean>;

  /**
   * Generate backup codes
   */
  generateBackupCodes(userId: string): Promise<string[]>;

  /**
   * Verify backup code
   */
  verifyBackupCode(userId: string, code: string): Promise<boolean>;
}

/**
 * Phone Authentication Service Interface
 */
export interface IPhoneService {
  /**
   * Send verification code to phone
   */
  sendVerificationCode(phoneNumber: string): Promise<{ success: boolean }>;

  /**
   * Verify phone number with code
   */
  verifyPhoneNumber(phoneNumber: string, code: string): Promise<{ success: boolean; token?: string }>;

  /**
   * Login with phone number
   */
  loginWithPhone(phoneNumber: string, code: string): Promise<AuthResponse>;
}
