"""Garantit le rattachement RBAC explicite des utilisateurs existants.

Cette migration termine la bascule depuis ``users.role`` vers les relations
RBAC. Elle est idempotente et ne supprime aucune donnée historique.
"""

from alembic import op
import sqlalchemy as sa


revision = "9e39f0a1b2c3"
down_revision = "9d28e9f0a1b2"
branch_labels = None
depends_on = None


def upgrade():
    bind = op.get_bind()

    bind.execute(sa.text(
        """INSERT INTO roles
           (slug, name, description, is_system, is_active, created_at, updated_at)
           SELECT 'admin', 'Administrateur système',
                  'Rôle système donnant toutes les permissions RBAC', 1, 1, NOW(), NOW()
           FROM DUAL
           WHERE NOT EXISTS (SELECT 1 FROM roles WHERE slug = 'admin')"""
    ))
    bind.execute(sa.text("UPDATE roles SET is_active = 1, is_system = 1 WHERE slug = 'admin'"))

    bind.execute(sa.text(
        """INSERT INTO permissions
           (code, name, module, action, description, is_active)
           SELECT '*', 'Accès complet', 'system', 'all',
                  'Accès complet accordé au rôle administrateur', 1
           FROM DUAL
           WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE code = '*')"""
    ))
    bind.execute(sa.text("UPDATE permissions SET is_active = 1 WHERE code = '*'"))

    bind.execute(sa.text(
        """INSERT INTO role_permissions (role_id, permission_id, effect)
           SELECT r.id, p.id, 'allow'
           FROM roles r CROSS JOIN permissions p
           WHERE r.slug = 'admin' AND p.code = '*'
             AND NOT EXISTS (
                 SELECT 1 FROM role_permissions rp
                 WHERE rp.role_id = r.id AND rp.permission_id = p.id
             )"""
    ))

    # Tous les comptes existants reçoivent explicitement admin. Le champ
    # users.role est conservé pour compatibilité d'affichage uniquement.
    bind.execute(sa.text(
        """INSERT INTO user_roles (user_id, role_id, assigned_at)
           SELECT u.id, r.id, NOW()
           FROM users u CROSS JOIN roles r
           WHERE r.slug = 'admin'
             AND NOT EXISTS (
                 SELECT 1 FROM user_roles ur
                 WHERE ur.user_id = u.id AND ur.role_id = r.id
             )"""
    ))


def downgrade():
    # Ne pas retirer les rattachements administrateurs : ils peuvent avoir été
    # modifiés après migration et leur suppression serait destructive.
    pass

