<?php

namespace DMD\LaLigaApi\Service\Common;

use DMD\LaLigaApi\Dto\NotificationDto;
use DMD\LaLigaApi\Entity\League;
use DMD\LaLigaApi\Entity\Notification;
use DMD\LaLigaApi\Entity\User;
use DMD\LaLigaApi\Enum\NotificationType;
use DMD\LaLigaApi\Enum\Role;
use DMD\LaLigaApi\Repository\CustomRoleRepository;
use DMD\LaLigaApi\Repository\TeamRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;

class NotificationFactory
{
    public function __construct(
        public CustomRoleRepository $customRoleRepository,
        public TeamRepository $teamRepository,
        public EntityManagerInterface $entityManager,
        public EmailSender $emailSender
    )
    {
    }

    /**
     * @throws TransportExceptionInterface
     */
    public function newJoinLeagueRequest(User $requestingUserEntity, League $leagueEntity, ?string $message): void
    {
        $leagueAdminEntity = $this->customRoleRepository->findUserByRoleName($leagueEntity->getId() . Role::LEAGUE_PRESIDENT->value);
        if (is_null($leagueAdminEntity))
        {
            throw new HttpException(Response::HTTP_NOT_FOUND,'Presidente de liga con id' . $leagueEntity->getId() .' no ha sido encontrado');
        }

        $requestingUserFullName = $requestingUserEntity->getFirstName() . ' '. $requestingUserEntity->getLastName();
        $notification = new Notification();
        $notification->setUserWhoFiredEvent($requestingUserEntity);
        $notification->setUserToNotify($leagueAdminEntity);
        $notification->setType(NotificationType::NEW_JOIN_LEAGUE_REQUEST->name);
        $notification->setMessage(
            $message ?? NotificationType::NEW_JOIN_LEAGUE_REQUEST->getMessage(
                $requestingUserFullName,
                $leagueEntity->getName()
            )
        );
        $notification->setLeague($leagueEntity);
        $this->entityManager->persist($notification);
        $this->entityManager->flush();
        $this->emailSender->newJoinLeagueRequest($leagueAdminEntity, $requestingUserEntity, $leagueEntity);
    }

    public function teamCaptainRequest(User $requestingUser, User $leagueAdminEntity, string $message, League $leagueEntity, int $teamId): void
    {
        $teamEntity = $this->teamRepository->find($teamId);
        if (is_null($teamEntity))
        {
            throw new HttpException(
                Response::HTTP_NOT_FOUND,
                "Equipo con ID $teamId no ha sido encontrado"
            );
        }
        $requestingUserFullName = $requestingUser->getFirstName() .' '. $requestingUser->getLastName();
        $notification = new Notification();
        $notification->setUserWhoFiredEvent($requestingUser);
        $notification->setUserToNotify($leagueAdminEntity);
        $notification->setType(NotificationType::NEW_CAPTAIN_REQUEST->name);
        $notification->setMessage($message ?? NotificationType::NEW_CAPTAIN_REQUEST->getMessage($requestingUserFullName, $teamEntity->getName()));
        $notification->setTeamId($teamId);
        $notification->setLeague($leagueEntity);
        $notification->setIsRead(false);
        $this->entityManager->persist($notification);
        $this->entityManager->flush();
        $this->emailSender->teamCaptainRequest($teamEntity, $leagueAdminEntity, $requestingUser, $leagueEntity);
    }
    public function joinLeagueRequestDeclined(User $rejectedUser, League $leagueEntity): void
    {
        $notification = new Notification();
        $notification->setUserToNotify($rejectedUser);
        $notification->setType(NotificationType::DECLINED_CAPTAIN_REQUEST->name);
        $notification->setMessage(
            NotificationType::DECLINED_JOIN_LEAGUE_REQUEST->getMessage(
                requestingUserFullName: null,
                entityName: $leagueEntity->getName()
            )
        );
        $notification->setIsRead(false);
        $this->entityManager->persist($notification);
        $this->entityManager->flush();
        $this->emailSender->joinLeagueRequestDeclined($rejectedUser, $leagueEntity);
    }
}