import { AdminUser } from '../entities/AdminUser';
import { Email } from '../value-objects/Email';
import { UserId } from '../value-objects/UserId';
import { UserRole } from '../value-objects/UserRole';
import { UserStatus } from '../value-objects/UserStatus';

export interface UserFilter {
  role?: UserRole;
  status?: UserStatus;
  email?: Email;
  search?: string;
}

export interface UserSort {
  field: 'email' | 'displayName' | 'createdAt' | 'lastLoginAt' | 'status';
  direction: 'asc' | 'desc';
}

export interface UserPagination {
  page: number;
  limit: number;
}

export interface UserListQuery {
  filter?: UserFilter;
  sort?: UserSort | undefined;
  pagination?: UserPagination | undefined;
}

export interface UserListResult {
  users: AdminUser[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface StoredAdminUser {
  id: string;
  email: string;
  roles: string[];
  status: string;
  displayName: string;
  createdAt: Date;
  updatedAt: Date;
  lastLoginAt?: Date;
  primaryDriverId?: string;
}

/**
 * Repository interface for AdminUser entity
 * Follows clean architecture - this is an output port from application layer
 */
export interface AdminUserRepository {
  /**
   * Find user by ID
   */
  findById(id: UserId): Promise<AdminUser | null>;

  /**
   * Find user by email
   */
  findByEmail(email: Email): Promise<AdminUser | null>;

  /**
   * Check if email exists
   */
  emailExists(email: Email): Promise<boolean>;

  /**
   * Check if user exists by ID
   */
  existsById(id: UserId): Promise<boolean>;

  /**
   * Check if user exists by email
   */
  existsByEmail(email: Email): Promise<boolean>;

  /**
   * List users with filtering, sorting, and pagination
   */
  list(query?: UserListQuery): Promise<UserListResult>;

  /**
   * Count users matching filter
   */
  count(filter?: UserFilter): Promise<number>;

  /**
   * Create a new user
   */
  create(user: AdminUser): Promise<AdminUser>;

  /**
   * Update existing user
   */
  update(user: AdminUser): Promise<AdminUser>;

  /**
   * Delete user (soft delete)
   */
  delete(id: UserId): Promise<void>;

  /**
   * Get user for storage
   */
  toStored(user: AdminUser): StoredAdminUser;

  /**
   * Rehydrate user from storage
   */
  fromStored(stored: StoredAdminUser): AdminUser;
}