-- Idempotent update: introduce assignable-roles mapping for privilege-escalation prevention.
-- Each role defines which other roles its members may assign to users.

CREATE TABLE IF NOT EXISTS `role_assignable_roles` (
  `role_id` INT UNSIGNED NOT NULL,
  `assignable_role_id` INT UNSIGNED NOT NULL,
  `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`role_id`, `assignable_role_id`),
  KEY `idx_rar_assignable` (`assignable_role_id`),
  CONSTRAINT `fk_rar_role` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_rar_assignable` FOREIGN KEY (`assignable_role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Permission: bypass assignable-roles check (super-admin)
INSERT INTO `permissions` (`key`, `description`, `active`, `is_system`)
VALUES ('roles.assign_all', 'permission.roles.assign_all', 1, 1)
ON DUPLICATE KEY UPDATE `key` = `key`;

-- Grant roles.assign_all to the ADMIN role
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
SELECT r.id, p.id
FROM roles r
JOIN permissions p ON p.`key` = 'roles.assign_all'
WHERE r.code = 'ADMIN';

-- Seed: ADMIN role can assign every existing role
INSERT IGNORE INTO `role_assignable_roles` (`role_id`, `assignable_role_id`)
SELECT admin_role.id, all_roles.id
FROM roles admin_role
CROSS JOIN roles all_roles
WHERE admin_role.code = 'ADMIN';
