<?php
/**
 * Nom du fichier: UserManager.php
 *
 * @author PEREDERII Antoine
 * @date 2023-11-25
 * @description Classe UserManager pour gérer les opérations liées aux utilisateurs.
 *
 * @package manager
 */

namespace Manager;

use Model\Athlete;
use Model\Coach;
use Model\RelationshipRequest;
use Model\User;
use Network\IAuthService;
use Network\IFriendRequestService;
use Shared\Validation;
use Stub\UserRepository;

class UserManager
{
    private IAuthService $authService;

    private ?User $currentUser;

    private DataManager $dataManager;

    private IFriendRequestService $relationshipService;

    

    public function __construct(DataManager $dataManager, IAuthService $authService, IFriendRequestService $relationshipService)
    {
        $this->authService = $authService;
        $this->dataManager = $dataManager;
        $this->relationshipService = $relationshipService;

    }
    public function getCurrentUser(): ?User
    {
        return $this->currentUser;
    }

    /**
     * Connecte un utilisateur avec les identifiants fournis.
     *
     * @param string $loginUser Le nom d'utilisateur.
     * @param string $passwordUser Le mot de passe de l'utilisateur.
     * @return bool Retourne true en cas de connexion réussie, sinon false.
     * @throws \Exception En cas d'erreur dans les informations d'identification.
     */
    public function login($emailUser, $passwordUser): bool
    {
        // Validate data format
        if (!Validation::val_email($emailUser)) {
            // The email is not valid
            return false;
        }

        if (!Validation::val_password($passwordUser)) {
            // The email is not valid
            return false;
        }


        if ($this->authService->login($emailUser, $passwordUser)) {
            $this->currentUser = $this->authService->getCurrentUser();
            // Check if the current user is correctly set
            if ($this->currentUser === null) {
                return false;
            }
            return true;
        } else {
            // Handle unsuccessful login (e.g., log error, throw exception, etc.)
            return false;
        }


    }

    public function addFriend(string $newFriend): bool
    {
        $newFriend = $this->dataManager->userRepository->getItemByName($newFriend, 0, 1);
        if ($newFriend === null) {
            throw new \Exception("User not found.");
        }

        if (in_array($newFriend, $this->currentUser->getRole()->getUsersList())) {
            throw new \Exception("Already friend");
        }
        var_dump("====================1=========================");
        if($this->relationshipService->sendRequest($this->currentUser, $newFriend)){
            return true;
        };
        return false;
    }

    public function respondToFriendRequest(int $requestId, bool $choice): bool
    {

        foreach ($this->currentUser->getRole()->getUsersRequests() as $key => $friendRequest) {
            /** @var RelationshipRequest $friendRequest */
            if ($friendRequest->getId() === $requestId) {
                /** @var User $userToAdd */
                $userToAdd = $this->dataManager->userRepository->getItemById($friendRequest->getToUser());
                if ($userToAdd === null) {
                    throw new \Exception("User not found with ID: " . $friendRequest->getFromUser());
                }
                if ($choice) {
                    try {
                        if($this->currentUser->getRole()->addUser($userToAdd)){
                            $this->dataManager->userRepository->addFriend($this->currentUser->getId(),$userToAdd->getId());
                            $this->relationshipService->acceptRequest($friendRequest);
                            $this->currentUser->getRole()->removeRequest($friendRequest);
                        };
                    }catch (\Exception $e){
                        $this->currentUser->getRole()->removeUser($userToAdd);
                        throw new \Exception("Failed to add friend" . $userToAdd->getUsername() );
                    }
                } else {
                    $this->relationshipService->declineRequest($friendRequest);
                }
                return true;
            }
        }
        return false;
    }

    public function searchUsersByName(string $name): array
    {
        return $this->dataManager->userRepository->getItemsByName($name, 0, 10);
    }

    public function getFriends(): array{
        return $this->currentUser->getRole()->getUsersList();
    }

    // NEED TO PERSIST
    public function deleteFriend(int $id): bool
    {
        /** @var User $userToRemove */
        $userToRemove = $this->dataManager->userRepository->getItemById($id);

        if ($userToRemove === null) {
            throw new \Exception("User not found with ID: " . $id);
        }

        if (!$this->currentUser->getRole()->removeUser($userToRemove)) {
            throw new \Exception("User with ID: " . $id . " is not in the current user's friends list.");
        }

        try {
            $this->dataManager->userRepository->deleteFriend($this->currentUser->getId(),$userToRemove->getId() );
        }catch (\Exception $e){
            throw new \Exception("Failed to delete friend" . $userToRemove->getUsername() );
        }

        return true;

    }

    // NEED TO PERSIST
    /**
     * Enregistre un nouvel utilisateur avec les informations fournies.
     *
     * @param string $loginUser Le nom d'utilisateur.
     * @param string $passwordUser Le mot de passe de l'utilisateur.
     * @param array $data Les données supplémentaires pour l'enregistrement.
     * @return bool Retourne true en cas d'enregistrement réussi, sinon false.
     * @throws \Exception En cas d'erreur lors de la validation des données ou de l'enregistrement.
     */
    public function register($loginUser, $passwordUser, $data): bool
    {
        // foreach ($data as $entry) {
        //     $isValid = Validation::val_string($entry);
        //     if (!$isValid) {
        //         throw new \Exception( "Entry '$entry' is not a valid string.");
        //     } 
        // }

        $roleName = $data['roleName'];
        if ($roleName !== "Athlete" && $roleName !== "Coach") {
            throw new \Exception("Rôle non valide");
        }

        if ($data['sexe'] !== "M" && $data['sexe'] !== "H") {
            throw new \Exception("Sexe non valide");
        }

        if ($this->authService->register($loginUser, $passwordUser, $data)) {
            $this->currentUser = $this->authService->getCurrentUser();
            return true;
        }
        return false;
    }

    /**
     * Déconnecte l'utilisateur actuel.
     *
     * @return bool Retourne true en cas de déconnexion réussie, sinon false.
     */
    public function deconnecter(): bool
    {
        if ($this->authService->logoutUser()) {
            return true;
        }
        return false;
    }

}
?>
