import { User } from '../../models/user.model';

/**
 * API Client interface
 */
export interface ApiClient {
  client_id: string;
  client_name: string;
  client_description?: string;
  allowed_scopes: string[];
  active: boolean;
  created_at: Date;
  updated_at: Date;
}

/**
 * API Client with secret
 */
export interface ApiClientWithSecret extends ApiClient {
  client_secret: string;
}

/**
 * Token payload interface
 */
export interface TokenPayload {
  sub: string;
  type: 'user' | 'client';
  email?: string;
  client_id?: string;
  roles?: string[];
  permissions?: string[];
  scopes?: string[];
  iat: number;
  exp: number;
  iss: string;
  aud: string;
}

/**
 * Authentication Service Interface
 * Defines operations for user authentication and API client management
 */
export interface IAuthService {
  /**
   * Authenticate user with email and password
   * @param email User email
   * @param password User password
   * @returns Tokens and user data
   */
  authenticateUser(email: string, password: string): Promise<{
    accessToken: string;
    refreshToken: string;
    expiresIn: number;
    user: Omit<User, 'password'>;
  }>;

  /**
   * Authenticate API client with client credentials
   * @param clientId Client ID
   * @param clientSecret Client secret
   * @param scope Requested scopes (space-separated)
   * @returns Access token and expiry
   */
  authenticateClient(
    clientId: string,
    clientSecret: string,
    scope?: string
  ): Promise<{
    accessToken: string;
    expiresIn: number;
    scope: string;
  }>;

  /**
   * Refresh access token using refresh token
   * @param refreshToken Refresh token
   * @returns New access token and expiry
   */
  refreshToken(refreshToken: string): Promise<{
    accessToken: string;
    expiresIn: number;
  }>;

  /**
   * Validate access token
   * @param token Access token
   * @returns Decoded token payload
   */
  validateToken(token: string): TokenPayload;

  /**
   * Create a new API client
   * @param clientData Client data
   * @returns Created client (with client_secret)
   */
  createApiClient(clientData: {
    client_name: string;
    client_description?: string;
    allowed_scopes?: string[];
  }): Promise<ApiClientWithSecret>;

  /**
   * Get all API clients
   * @param page Page number
   * @param limit Items per page
   * @param filters Optional filters
   * @returns API clients and pagination info
   */
  getApiClients(
    page?: number,
    limit?: number,
    filters?: Record<string, any>
  ): Promise<{
    clients: Omit<ApiClient, 'client_secret'>[];
    pagination: {
      page: number;
      limit: number;
      totalCount: number;
      totalPages: number;
      hasNext: boolean;
      hasPrev: boolean;
    };
  }>;

  /**
   * Get API client by ID
   * @param clientId Client ID
   * @returns API client (without client_secret)
   */
  getApiClientById(clientId: string): Promise<Omit<ApiClient, 'client_secret'> | null>;

  /**
   * Update API client
   * @param clientId Client ID
   * @param clientData Client data to update
   * @returns Updated client (without client_secret)
   */
  updateApiClient(
    clientId: string,
    clientData: {
      client_name?: string;
      client_description?: string;
      allowed_scopes?: string[];
      active?: boolean;
    }
  ): Promise<Omit<ApiClient, 'client_secret'> | null>;

  /**
   * Delete API client
   * @param clientId Client ID
   * @returns Success flag
   */
  deleteApiClient(clientId: string): Promise<boolean>;

  /**
   * Regenerate client secret
   * @param clientId Client ID
   * @returns New client secret
   */
  regenerateClientSecret(clientId: string): Promise<string | null>;
}
