<?php

declare(strict_types=1);

namespace App\Service;

use App\Entity\Access\Access;
use App\Entity\Core\File;
use App\Entity\Core\Notification;
use App\Enum\Core\NotificationTypeEnum;
use Doctrine\ORM\EntityManagerInterface;

class Notifier
{
    public function __construct(
        private EntityManagerInterface $em,
        private MercureHub $mercureHub,
    ) {
    }

    /**
     * @param list<string> $message
     */
    protected function createNotification(
        Access $access,
        string $name,
        NotificationTypeEnum $type,
        array $message,
        ?string $link = null,
    ): Notification {
        $now = new \DateTime();

        $notification = new Notification();
        /* @phpstan-ignore-next-line Je ne sais pas d'où vient cette erreur, mais elle c'est un faux positif */
        $notification->setName($name)
            ->setRecipientAccess($access)
            ->setRecipientOrganization($access->getOrganization())
            ->setType($type)
            ->setMessage($message)
            ->setLink($link)
            ->setCreateDate($now)
            ->setUpdateDate($now);

        return $notification;
    }

    /**
     * @param array<string> $message
     */
    public function notify(
        Access $access,
        string $name,
        NotificationTypeEnum $type,
        array $message,
        ?string $link = null,
    ): Notification {
        $notification = $this->createNotification($access, $name, $type, $message, $link);

        $this->em->persist($notification);
        $this->em->flush();

        $this->mercureHub->publishCreate($access->getId(), $notification);

        return $notification;
    }

    public function notifyExport(
        Access $access,
        File $file,
    ): Notification {
        return $this->notify(
            $access,
            'export',
            NotificationTypeEnum::FILE,
            ['fileName' => $file->getName()],
            '/api/files/'.$file->getId().'/download'
        );
    }

    /**
     * @param array<string> $message
     */
    public function notifyMessage(
        Access $access,
        array $message,
    ): Notification {
        return $this->notify(
            $access,
            'message',
            NotificationTypeEnum::MESSAGE,
            $message
        );
    }

    /**
     * @param list<string> $message
     */
    public function notifySystem(
        Access $access,
        array $message,
    ): Notification {
        return $this->notify(
            $access,
            'message',
            NotificationTypeEnum::SYSTEM,
            $message
        );
    }

    /**
     * @param list<string> $message
     */
    public function notifyError(
        Access $access,
        string $name,
        array $message,
    ): Notification {
        return $this->notify(
            $access,
            $name,
            NotificationTypeEnum::ERROR,
            $message
        );
    }
}
