<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\EventHandler;

use App\Administration\Application\Service\Cache\PaginatedQueryCache;
use App\Administration\Domain\Event\AffectationRetiree;
use App\Administration\Domain\Event\ClasseArchivee;
use App\Administration\Domain\Event\ClasseCreee;
use App\Administration\Domain\Event\ClasseModifiee;
use App\Administration\Domain\Event\CompteActive;
use App\Administration\Domain\Event\CompteCreated;
use App\Administration\Domain\Event\DroitImageModifie;
use App\Administration\Domain\Event\EleveInscrit;
use App\Administration\Domain\Event\EnseignantAffecte;
use App\Administration\Domain\Event\ImportElevesTermine;
use App\Administration\Domain\Event\ImportEnseignantsTermine;
use App\Administration\Domain\Event\InvitationParentActivee;
use App\Administration\Domain\Event\InvitationParentEnvoyee;
use App\Administration\Domain\Event\InvitationRenvoyee;
use App\Administration\Domain\Event\MatiereCreee;
use App\Administration\Domain\Event\MatiereModifiee;
use App\Administration\Domain\Event\MatiereSupprimee;
use App\Administration\Domain\Event\ParentDelieDEleve;
use App\Administration\Domain\Event\ParentLieAEleve;
use App\Administration\Domain\Event\RoleAttribue;
use App\Administration\Domain\Event\RoleRetire;
use App\Administration\Domain\Event\UtilisateurBloque;
use App\Administration\Domain\Event\UtilisateurDebloque;
use App\Administration\Domain\Event\UtilisateurInvite;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

final readonly class PaginatedQueryCacheInvalidator
{
    public function __construct(
        private PaginatedQueryCache $cache,
    ) {
    }

    // === Users ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onUtilisateurInvite(UtilisateurInvite $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onUtilisateurBloque(UtilisateurBloque $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onUtilisateurDebloque(UtilisateurDebloque $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onCompteActive(CompteActive $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onCompteCreated(CompteCreated $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onEleveInscrit(EleveInscrit $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('users', $tenantId);
        $this->cache->invalidate('students_image_rights', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onRoleAttribue(RoleAttribue $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onRoleRetire(RoleRetire $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onInvitationRenvoyee(InvitationRenvoyee $event): void
    {
        $this->cache->invalidate('users', (string) $event->tenantId);
    }

    // === Classes (also invalidates assignments: class names appear in assignment list) ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onClasseCreee(ClasseCreee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('classes', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onClasseModifiee(ClasseModifiee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('classes', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onClasseArchivee(ClasseArchivee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('classes', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    // === Subjects (also invalidates assignments: subject names appear in assignment list) ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onMatiereCreee(MatiereCreee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('subjects', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onMatiereModifiee(MatiereModifiee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('subjects', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onMatiereSupprimee(MatiereSupprimee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('subjects', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }

    // === Assignments ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onEnseignantAffecte(EnseignantAffecte $event): void
    {
        $this->cache->invalidate('assignments', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onAffectationRetiree(AffectationRetiree $event): void
    {
        $this->cache->invalidate('assignments', (string) $event->tenantId);
    }

    // === Parent invitations ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onInvitationParentEnvoyee(InvitationParentEnvoyee $event): void
    {
        $this->cache->invalidate('parent_invitations', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onInvitationParentActivee(InvitationParentActivee $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('parent_invitations', $tenantId);
        $this->cache->invalidate('users', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onParentLieAEleve(ParentLieAEleve $event): void
    {
        $this->cache->invalidate('parent_invitations', (string) $event->tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onParentDelieDEleve(ParentDelieDEleve $event): void
    {
        $this->cache->invalidate('parent_invitations', (string) $event->tenantId);
    }

    // === Image rights ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onDroitImageModifie(DroitImageModifie $event): void
    {
        $this->cache->invalidate('students_image_rights', (string) $event->tenantId);
    }

    // === Imports (invalidate multiple caches) ===

    #[AsMessageHandler(bus: 'event.bus')]
    public function onImportElevesTermine(ImportElevesTermine $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('users', $tenantId);
        $this->cache->invalidate('students_image_rights', $tenantId);
        $this->cache->invalidate('classes', $tenantId);
    }

    #[AsMessageHandler(bus: 'event.bus')]
    public function onImportEnseignantsTermine(ImportEnseignantsTermine $event): void
    {
        $tenantId = (string) $event->tenantId;
        $this->cache->invalidate('users', $tenantId);
        $this->cache->invalidate('assignments', $tenantId);
    }
}
