<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * Module Sites - Ticket 2/4 : rattachement User ↔ Site.
 *
 * Introduit deux nouvelles structures sur le schema existant :
 *  - la table de jointure `user_site` (M2M) : liste des sites autorises
 *    pour chaque utilisateur.
 *  - la colonne `"user".current_site_id` (M2O nullable) : site actuellement
 *    selectionne par l'utilisateur pour son contexte UX.
 *
 * Cascades choisies :
 *  - `user_site.user_id` → `ON DELETE CASCADE` : supprimer un user purge
 *    naturellement ses rattachements.
 *  - `user_site.site_id` → `ON DELETE CASCADE` : supprimer un site purge
 *    tous les rattachements a ce site.
 *  - `"user".current_site_id` → `ON DELETE SET NULL` : supprimer un site
 *    repasse le currentSite des users concernes a NULL (plutot que de
 *    detruire les users, ce qui serait catastrophique).
 *
 * Note sur l'emplacement du fichier (namespace racine `DoctrineMigrations`)
 *  Conforme a l'exception documentee dans `CLAUDE.md` : tant que le bug de
 *  tri alphabetique des MigrationsComparator Doctrine 3.x n'est pas resolu,
 *  toute migration touchant a la topologie des tables (creation, FKs
 *  cross-module) vit au namespace racine. La migration croise ici les tables
 *  `"user"` (module Core) et `site` (module Sites) — placement racine donc
 *  justifie pour garantir l'ordre d'execution deterministe vis-a-vis des
 *  deux migrations d'init deja presentes.
 */
final class Version20260417150000 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Module Sites : table user_site (M2M) + colonne user.current_site_id (M2O SET NULL).';
    }

    public function up(Schema $schema): void
    {
        // 1) Creation de la table de jointure user_site.
        $this->addSql(<<<'SQL'
                CREATE TABLE user_site (
                  user_id INT NOT NULL,
                  site_id INT NOT NULL,
                  PRIMARY KEY (user_id, site_id)
                )
            SQL);
        $this->addSql('CREATE INDEX IDX_user_site_user ON user_site (user_id)');
        $this->addSql('CREATE INDEX IDX_user_site_site ON user_site (site_id)');
        $this->addSql(<<<'SQL'
                ALTER TABLE user_site
                ADD CONSTRAINT FK_user_site_user
                FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE
            SQL);
        $this->addSql(<<<'SQL'
                ALTER TABLE user_site
                ADD CONSTRAINT FK_user_site_site
                FOREIGN KEY (site_id) REFERENCES site (id) ON DELETE CASCADE
            SQL);

        // 2) Ajout de la colonne nullable user.current_site_id + FK SET NULL.
        $this->addSql('ALTER TABLE "user" ADD current_site_id INT DEFAULT NULL');
        $this->addSql('CREATE INDEX IDX_user_current_site ON "user" (current_site_id)');
        $this->addSql(<<<'SQL'
                ALTER TABLE "user"
                ADD CONSTRAINT FK_user_current_site
                FOREIGN KEY (current_site_id) REFERENCES site (id) ON DELETE SET NULL
            SQL);
    }

    public function down(Schema $schema): void
    {
        // Rollback en ordre inverse : enfants avant parents.
        $this->addSql('ALTER TABLE "user" DROP CONSTRAINT FK_user_current_site');
        $this->addSql('DROP INDEX IDX_user_current_site');
        $this->addSql('ALTER TABLE "user" DROP current_site_id');

        $this->addSql('ALTER TABLE user_site DROP CONSTRAINT FK_user_site_site');
        $this->addSql('ALTER TABLE user_site DROP CONSTRAINT FK_user_site_user');
        $this->addSql('DROP TABLE user_site');
    }
}
