package com.social.media.domain.user.repository;

import com.social.media.domain.user.aggregate.User;
import com.social.media.domain.user.valueobject.*;
import com.social.media.domain.company.valueobject.CompanyId;
import com.social.media.domain.shared.valueobject.Email;
import com.social.media.domain.shared.enums.UserType;
import com.social.media.domain.shared.enums.UserStatus;

import java.util.List;
import java.util.Optional;

/**
 * Repository interface for User aggregate
 * This is a port in the hexagonal architecture
 */
public interface UserRepository {
    
    /**
     * Save a user (create or update)
     */
    User save(User user);
    
    /**
     * Find user by ID
     */
    Optional<User> findById(UserId id);
    
    /**
     * Find user by email
     */
    Optional<User> findByEmail(Email email);
    
    /**
     * Find user by CPF
     */
    Optional<User> findByCpf(Cpf cpf);
    
    /**
     * Check if email exists (for validation)
     */
    boolean existsByEmail(Email email);
    
    /**
     * Check if CPF exists (for validation)
     */
    boolean existsByCpf(Cpf cpf);
    
    /**
     * Find users by company
     */
    List<User> findByCompany(CompanyId companyId);
    
    /**
     * Find users by status
     */
    List<User> findByStatus(UserStatus status);
    
    /**
     * Find users by type
     */
    List<User> findByType(UserType type);
    
    /**
     * Find users by company and status
     */
    List<User> findByCompanyAndStatus(CompanyId companyId, UserStatus status);
    
    /**
     * Find users by company and type
     */
    List<User> findByCompanyAndType(CompanyId companyId, UserType type);
    
    /**
     * Find active users (not deleted)
     */
    List<User> findActiveUsers();
    
    /**
     * Find users by parent user
     */
    List<User> findByParentUser(UserId parentUserId);
    
    /**
     * Find user by verification token
     */
    Optional<User> findByVerificationToken(String token);
    
    /**
     * Find user by password reset token
     */
    Optional<User> findByPasswordResetToken(String token);
    
    /**
     * Delete user (hard delete - use with caution)
     */
    void delete(UserId id);
    
    /**
     * Get total count of users
     */
    long countUsers();
    
    /**
     * Get count of active users
     */
    long countActiveUsers();
    
    /**
     * Get count by company
     */
    long countByCompany(CompanyId companyId);
    
    /**
     * Get count by user type
     */
    long countByType(UserType type);
    
    /**
     * Check if SUPER_ADMIN already exists
     */
    boolean existsSuperAdmin();
    
    /**
     * Find SUPER_ADMIN user
     */
    Optional<User> findSuperAdmin();
    
    /**
     * Check if user exists by type and company
     */
    boolean existsByTypeAndCompany(UserType type, CompanyId companyId);
}
