import mysql.connector
from mysql.connector import Error
import argparse
import json
import sys

# Reconfigure stdout to support UTF-8 if available
if hasattr(sys.stdout, 'reconfigure'):
    try:
        sys.stdout.reconfigure(encoding='utf-8')
    except Exception:
        pass

# Define built-in role permission matrices exactly as they were hardcoded in app.py
BUILTIN_ROLES = {
    'SUPER ADMIN': {
        'description': 'Accès complet et configuration du système',
        'color': '#ef4444',
        'icon': 'fa-user-shield',
        'permissions': {k: True for k in [
            'interventions', 'equipements', 'pieces', 'preventifs', 'ordres',
            'fournisseurs', 'commandes', 'familles', 'operations', 'operateurs',
            'qualifications', 'outillages', 'gammes', 'constats', 'rapports',
            'utilisateurs', 'can_edit', 'can_add', 'can_delete'
        ]}
    },
    'DIRECTION': {
        'description': 'Accès complet en lecture et modification, pas de suppression',
        'color': '#3b82f6',
        'icon': 'fa-user-tie',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': True, 'preventifs': True, 'ordres': True,
            'fournisseurs': True, 'commandes': True, 'familles': True, 'operations': True, 'operateurs': True,
            'qualifications': True, 'outillages': True, 'gammes': True, 'constats': True, 'rapports': True,
            'utilisateurs': True, 'can_edit': True, 'can_add': True, 'can_delete': False
        }
    },
    'CHEF DEPARTEMENT': {
        'description': 'Gestion du département, pas d\'administration des utilisateurs',
        'color': '#10b981',
        'icon': 'fa-user-cog',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': True, 'preventifs': True, 'ordres': True,
            'fournisseurs': True, 'commandes': True, 'familles': True, 'operations': True, 'operateurs': True,
            'qualifications': True, 'outillages': True, 'gammes': True, 'constats': True, 'rapports': True,
            'utilisateurs': False, 'can_edit': True, 'can_add': True, 'can_delete': False
        }
    },
    'STM': {
        'description': 'Service Technique Maintenance - Accès complet maintenance',
        'color': '#6366f1',
        'icon': 'fa-tools',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': True, 'preventifs': True, 'ordres': True,
            'fournisseurs': True, 'commandes': True, 'familles': True, 'operations': True, 'operateurs': True,
            'qualifications': True, 'outillages': True, 'gammes': True, 'constats': True, 'rapports': True,
            'utilisateurs': False, 'can_edit': True, 'can_add': True, 'can_delete': True
        }
    },
    'SIM': {
        'description': 'Service Intervention Maintenance - Pas de suppression',
        'color': '#8b5cf6',
        'icon': 'fa-wrench',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': True, 'preventifs': True, 'ordres': True,
            'fournisseurs': True, 'commandes': True, 'familles': True, 'operations': True, 'operateurs': True,
            'qualifications': True, 'outillages': True, 'gammes': True, 'constats': True, 'rapports': True,
            'utilisateurs': False, 'can_edit': True, 'can_add': True, 'can_delete': False
        }
    },
    'CEM': {
        'description': 'Chef Équipe Maintenance - Accès complet maintenance',
        'color': '#f59e0b',
        'icon': 'fa-users-cog',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': True, 'preventifs': True, 'ordres': True,
            'fournisseurs': True, 'commandes': True, 'familles': True, 'operations': True, 'operateurs': True,
            'qualifications': True, 'outillages': True, 'gammes': True, 'constats': True, 'rapports': True,
            'utilisateurs': False, 'can_edit': True, 'can_add': True, 'can_delete': True
        }
    },
    'PRODUCTION': {
        'description': 'Création et suivi des demandes d\'intervention de production',
        'color': '#ec4899',
        'icon': 'fa-industry',
        'permissions': {
            'interventions': True, 'equipements': False, 'pieces': False, 'preventifs': False, 'ordres': False,
            'fournisseurs': False, 'commandes': False, 'familles': False, 'operations': False, 'operateurs': False,
            'qualifications': False, 'outillages': False, 'gammes': False, 'constats': False, 'rapports': False,
            'utilisateurs': False, 'can_edit': False, 'can_add': True, 'can_delete': False
        }
    },
    'LABORATOIRE': {
        'description': 'Création et suivi des demandes d\'intervention de laboratoire',
        'color': '#14b8a6',
        'icon': 'fa-flask',
        'permissions': {
            'interventions': True, 'equipements': False, 'pieces': False, 'preventifs': False, 'ordres': False,
            'fournisseurs': False, 'commandes': False, 'familles': False, 'operations': False, 'operateurs': False,
            'qualifications': False, 'outillages': False, 'gammes': False, 'constats': False, 'rapports': False,
            'utilisateurs': False, 'can_edit': False, 'can_add': True, 'can_delete': False
        }
    },
    'AQ': {
        'description': 'Assurance Qualité - Accès aux rapports et constats',
        'color': '#06b6d4',
        'icon': 'fa-clipboard-check',
        'permissions': {
            'interventions': True, 'equipements': True, 'pieces': False, 'preventifs': True, 'ordres': False,
            'fournisseurs': False, 'commandes': False, 'familles': False, 'operations': False, 'operateurs': False,
            'qualifications': False, 'outillages': False, 'gammes': False, 'constats': True, 'rapports': True,
            'utilisateurs': False, 'can_edit': True, 'can_add': True, 'can_delete': False
        }
    },
    'UTILITE': {
        'description': 'Création et suivi des demandes d\'intervention des utilités',
        'color': '#6b7280',
        'icon': 'fa-leaf',
        'permissions': {
            'interventions': True, 'equipements': False, 'pieces': False, 'preventifs': False, 'ordres': False,
            'fournisseurs': False, 'commandes': False, 'familles': False, 'operations': False, 'operateurs': False,
            'qualifications': False, 'outillages': False, 'gammes': False, 'constats': False, 'rapports': False,
            'utilisateurs': False, 'can_edit': False, 'can_add': True, 'can_delete': False
        }
    }
}

NOTIF_DEFAULTS = {
    'nouvelle_intervention': '1',
    'intervention_urgente':  '1',
    'intervention_traitee':  '0',
    'stock_alerte':          '0',
    'maintenance_preventive':'0',
    'ordre_travail':         '0'
}

def migrate(dry_run=False):
    db_config = {
        'host': 'localhost',
        'user': 'root',
        'password': '',
        'database': 'gestion_mei_1'
    }

    print(f"Connexion à la base de données {db_config['database']}...")
    try:
        connection = mysql.connector.connect(**db_config)
    except Error as e:
        print(f"Erreur de connexion: {e}")
        return

    cursor = connection.cursor()

    # Define table creation SQL
    create_roles_table_sql = """
    CREATE TABLE IF NOT EXISTS `roles` (
      `id`          INT(11)      NOT NULL AUTO_INCREMENT,
      `name`        VARCHAR(50)  NOT NULL,
      `description` VARCHAR(255) DEFAULT NULL,
      `is_builtin`  TINYINT(1)   NOT NULL DEFAULT 0,
      `color`       VARCHAR(20)  DEFAULT '#6366f1',
      `icon`        VARCHAR(50)  DEFAULT 'fa-user-tag',

      -- Module access (16 keys)
      `interventions`   TINYINT(1) NOT NULL DEFAULT 0,
      `equipements`     TINYINT(1) NOT NULL DEFAULT 0,
      `pieces`          TINYINT(1) NOT NULL DEFAULT 0,
      `preventifs`      TINYINT(1) NOT NULL DEFAULT 0,
      `ordres`          TINYINT(1) NOT NULL DEFAULT 0,
      `fournisseurs`    TINYINT(1) NOT NULL DEFAULT 0,
      `commandes`       TINYINT(1) NOT NULL DEFAULT 0,
      `familles`        TINYINT(1) NOT NULL DEFAULT 0,
      `operations`      TINYINT(1) NOT NULL DEFAULT 0,
      `operateurs`      TINYINT(1) NOT NULL DEFAULT 0,
      `qualifications`  TINYINT(1) NOT NULL DEFAULT 0,
      `outillages`      TINYINT(1) NOT NULL DEFAULT 0,
      `gammes`          TINYINT(1) NOT NULL DEFAULT 0,
      `constats`        TINYINT(1) NOT NULL DEFAULT 0,
      `rapports`        TINYINT(1) NOT NULL DEFAULT 0,
      `utilisateurs`    TINYINT(1) NOT NULL DEFAULT 0,

      -- Action flags (3 keys)
      `can_edit`    TINYINT(1) NOT NULL DEFAULT 0,
      `can_add`     TINYINT(1) NOT NULL DEFAULT 0,
      `can_delete`  TINYINT(1) NOT NULL DEFAULT 0,

      -- Notification defaults (JSON string)
      `notif_config_default` TEXT DEFAULT NULL,

      `created_at`  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,

      PRIMARY KEY (`id`),
      UNIQUE KEY `uq_roles_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
    """

    # Alter user table SQL
    alter_user_table_sql = "ALTER TABLE `user` ADD COLUMN IF NOT EXISTS `notif_config` TEXT DEFAULT NULL;"

    if dry_run:
        print("\n--- MODE DRY RUN : SQL statements that would be executed ---")
        print("\n1. Créer la table `roles` :")
        print(create_roles_table_sql.strip())
        print("\n2. Altérer la table `user` pour ajouter `notif_config` :")
        print(alter_user_table_sql.strip())
        
        print("\n3. Insérer/mettre à jour les rôles intégrés :")
        for role_name, data in BUILTIN_ROLES.items():
            perms = data['permissions']
            columns = ['name', 'description', 'is_builtin', 'color', 'icon', 'notif_config_default'] + list(perms.keys())
            values = [role_name, data['description'], 1, data['color'], data['icon'], json.dumps(NOTIF_DEFAULTS)] + [1 if perms[k] else 0 for k in perms]
            
            placeholders = ", ".join(["%s"] * len(columns))
            cols_str = ", ".join([f"`{c}`" for c in columns])
            
            # Format preview values safely
            formatted_values = []
            for val in values:
                if isinstance(val, str):
                    formatted_values.append(f"'{val}'")
                else:
                    formatted_values.append(str(val))
            val_str = ", ".join(formatted_values)
            
            print(f"INSERT IGNORE INTO `roles` ({cols_str}) VALUES ({val_str});")
        print("\n-----------------------------------------------------------")
        cursor.close()
        connection.close()
        return

    # Non dry-run execution
    print("Création de la table `roles` si elle n'existe pas...")
    cursor.execute(create_roles_table_sql)
    
    print("Mise à jour de la table `user` pour ajouter la colonne `notif_config`...")
    try:
        cursor.execute(alter_user_table_sql)
    except Error as e:
        # Ignore if column already exists or command is not supported by MySQL version (e.g. IF NOT EXISTS on older MySQL)
        # We catch and log just in case, but usually mysql-connector supports it or we can fallback
        print(f"Info/Avertissement altération table user: {e}")

    print("Insertion des rôles intégrés...")
    for role_name, data in BUILTIN_ROLES.items():
        perms = data['permissions']
        columns = ['name', 'description', 'is_builtin', 'color', 'icon', 'notif_config_default'] + list(perms.keys())
        values = [role_name, data['description'], 1, data['color'], data['icon'], json.dumps(NOTIF_DEFAULTS)] + [1 if perms[k] else 0 for k in perms]
        
        placeholders = ", ".join(["%s"] * len(columns))
        cols_str = ", ".join([f"`{c}`" for c in columns])
        
        # Using INSERT INTO ... ON DUPLICATE KEY UPDATE to make it idempotent and update values if changed
        update_str = ", ".join([f"`{c}` = VALUES(`{c}`)" for c in columns if c != 'name'])
        sql = f"INSERT INTO `roles` ({cols_str}) VALUES ({placeholders}) ON DUPLICATE KEY UPDATE {update_str}"
        
        cursor.execute(sql, tuple(values))

    connection.commit()
    print("Migration terminée avec succès !")

    cursor.close()
    connection.close()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Migration des rôles pour GMAO BIOGALENIC")
    parser.add_argument('--dry-run', action='store_true', help="Afficher les requêtes SQL sans les exécuter")
    args = parser.parse_args()
    migrate(dry_run=args.dry_run)
