#!/usr/bin/env python3
import sqlite3
import random
from datetime import datetime, timedelta
import math

# Configuration de la base de données
DB_PATH = 'database/sqdc.db'

# Catégories
CATEGORIES = [
    {'id': 1, 'name': 'Sécurité', 'emoji': '🛡️', 'description': 'Indicateurs de sécurité et prévention des accidents'},
    {'id': 2, 'name': 'Qualité', 'emoji': '🎯', 'description': 'Indicateurs de qualité des produits'},
    {'id': 3, 'name': 'Délais & Livraison', 'emoji': '⏱️', 'description': 'Indicateurs de délais et livraison'},
    {'id': 4, 'name': 'Coûts', 'emoji': '💰', 'description': 'Indicateurs de coûts de production'},
    {'id': 5, 'name': 'Maintenance', 'emoji': '🔧', 'description': 'Indicateurs de maintenance'}
]

# KPIs avec fréquences
KPIS = [
    # SÉCURITÉ (1 mesure par jour)
    {'id': 1, 'category_id': 1, 'name': 'Taux de Fréquence (TF)', 'unit': 'par 1M heures', 'target': 1.0, 'frequency': 'daily', 'formula': '(Nombre d\'Accidents avec Arrêt / Nombre d\'Heures Travaillées) × 1000000', 'description': 'Mesurer la fréquence des accidents avec arrêt.'},
    {'id': 2, 'category_id': 1, 'name': 'Nombre d\'Incidents/Near Miss', 'unit': 'incidents', 'target': 8, 'frequency': 'daily', 'formula': 'Compte des rapports d\'incidents', 'description': 'Évaluer la culture de sécurité.'},
    {'id': 3, 'category_id': 1, 'name': 'Taux de Conformité aux Audits', 'unit': '%', 'target': 95, 'frequency': 'weekly', 'formula': '(Points Conformes / Total Points) × 100', 'description': 'Mesurer le respect des procédures.'},
    
    # QUALITÉ (toutes les 10 minutes)
    {'id': 4, 'category_id': 2, 'name': 'Taux de Rebut (Scrap Rate)', 'unit': '%', 'target': 1.5, 'frequency': 'per_10min', 'formula': '(Unités Rebutées / Unités Produites) × 100', 'description': 'Mesurer le % d\'unités jetées.'},
    {'id': 5, 'category_id': 2, 'name': 'Taux de Retouche (Rework Rate)', 'unit': '%', 'target': 2.0, 'frequency': 'per_10min', 'formula': '(Unités Retouchées / Unités Totales) × 100', 'description': 'Mesurer le % d\'unités retouchées.'},
    {'id': 6, 'category_id': 2, 'name': 'Nombre de Défauts par Unité (DPU)', 'unit': 'défauts/unité', 'target': 0.5, 'frequency': 'per_10min', 'formula': 'Défauts Totaux / Unités Inspectées', 'description': 'Mesurer le nombre moyen de défauts.'},
    {'id': 7, 'category_id': 2, 'name': 'Taux de Retours Clients', 'unit': '%', 'target': 0.8, 'frequency': 'daily', 'formula': '(Unités Retournées / Unités Vendues) × 100', 'description': 'Mesurer l\'impact de la non-qualité.'},
    {'id': 8, 'category_id': 2, 'name': 'Taux de rendement synthétique (TRS)', 'unit': '%', 'target': 85, 'frequency': 'per_30min', 'formula': 'Pièces bonnes × Temps cycle / Temps ouverture', 'description': 'Rendement global de la ligne.'},
    {'id': 9, 'category_id': 2, 'name': 'Efficacité Globale de l\'Équipement (OEE)', 'unit': '%', 'target': 80, 'frequency': 'per_30min', 'formula': 'Disponibilité × Performance × Qualité', 'description': 'Mesurer l\'efficacité combinée.'},
    
    # DÉLAIS (toutes les heures)
    {'id': 10, 'category_id': 3, 'name': 'Taux de Respect du Plan', 'unit': '%', 'target': 95, 'frequency': 'hourly', 'formula': '(Produite / Planifiée) × 100', 'description': 'Mesurer la capacité à atteindre le volume.'},
    {'id': 11, 'category_id': 3, 'name': 'Temps de Cycle (Cycle Time)', 'unit': 'min/unité', 'target': 50, 'frequency': 'per_10min', 'formula': 'Temps Total / Nombre d\'Unités', 'description': 'Mesurer le temps par unité.'},
    {'id': 12, 'category_id': 3, 'name': 'Tack Time', 'unit': 'min/unité', 'target': 50, 'frequency': 'per_10min', 'formula': 'Temps production / Pièces demandées', 'description': 'Temps de production requis par unité.'},
    {'id': 13, 'category_id': 3, 'name': 'Temps d\'Arrêt Imprévu (Downtime)', 'unit': 'h/jour', 'target': 1.5, 'frequency': 'daily', 'formula': 'Somme des Arrêts Non Planifiés', 'description': 'Mesurer l\'arrêt non planifié.'},
    
    # COÛTS (quotidiennement)
    {'id': 14, 'category_id': 4, 'name': 'Coût par Unité (CPU)', 'unit': '€', 'target': 240, 'frequency': 'daily', 'formula': 'Coût Total / Unités Produites', 'description': 'Mesurer l\'efficacité des coûts.'},
    {'id': 15, 'category_id': 4, 'name': 'Productivité de la Main-d\'œuvre', 'unit': 'unités/h', 'target': 8.0, 'frequency': 'hourly', 'formula': 'Unités Produites / Heures Main-d\'œuvre', 'description': 'Mesurer l\'efficacité de l\'équipe.'},
    {'id': 16, 'category_id': 4, 'name': 'Coût des Non-Qualité (CNQ)', 'unit': '€', 'target': 10000, 'frequency': 'daily', 'formula': 'Rebuts + Retouches + Retours', 'description': 'Mesurer le coût des défauts.'},
    
    # MAINTENANCE (tous les 3 jours)
    {'id': 17, 'category_id': 5, 'name': 'Temps Moyen Entre Pannes (MTBF)', 'unit': 'heures', 'target': 400, 'frequency': 'per_3days', 'formula': 'Temps Fonctionnement / Pannes', 'description': 'Mesurer la fiabilité.'},
    {'id': 18, 'category_id': 5, 'name': 'Temps Moyen de Réparation (MTTR)', 'unit': 'heures', 'target': 2.5, 'frequency': 'per_3days', 'formula': 'Temps Réparation / Pannes', 'description': 'Mesurer la rapidité.'},
    {'id': 19, 'category_id': 5, 'name': 'Ratio Maintenance Préventive/Corrective', 'unit': '%', 'target': 70, 'frequency': 'weekly', 'formula': 'Heures MP / (MP + MC)', 'description': 'Évaluer la stratégie.'},
    {'id': 20, 'category_id': 5, 'name': 'Taux d\'Achèvement du Plan Préventif', 'unit': '%', 'target': 95, 'frequency': 'weekly', 'formula': '(Tâches Terminées / Tâches Planifiées) × 100', 'description': 'Mesurer le respect du plan.'},
    {'id': 21, 'category_id': 5, 'name': 'Coût de Maintenance par Unité Produite', 'unit': '€', 'target': 30, 'frequency': 'daily', 'formula': 'Coûts Maintenance / Unités Produites', 'description': 'Relier dépenses à production.'}
]

def get_frequency_minutes(frequency):
    """Retourne le nombre de minutes entre les mesures"""
    frequencies = {
        'per_10min': 10,
        'per_30min': 30,
        'hourly': 60,
        'daily': 1440,  # 24h
        'weekly': 10080,  # 7 jours
        'per_3days': 4320  # 3 jours
    }
    return frequencies.get(frequency, 1440)

def generate_value(kpi_id, target, variance_range=0.2):
    """Génère une valeur réaliste autour de la cible"""
    variance = (random.random() - 0.5) * 2 * variance_range
    value = target * (1 + variance)
    
    # Ajouter du bruit réaliste pour certains KPI
    if kpi_id in [4, 5, 6, 11, 12]:  # Qualité et délais - plus de variabilité
        noise = (random.random() - 0.5) * 0.3 * target
        value += noise
    
    return max(0, round(value, 2))

def determine_status(kpi_id, value, target):
    """Détermine le statut (good, warning, critical)"""
    tolerance = abs(target * 0.1)
    
    # KPI où plus bas est mieux
    if kpi_id in [2, 4, 5, 6, 13, 16]:
        if value > target + tolerance * 2:
            return 'critical'
        elif value > target + tolerance:
            return 'warning'
    else:
        # KPI où plus haut est mieux
        if value < target - tolerance * 2:
            return 'critical'
        elif value < target - tolerance:
            return 'warning'
    
    return 'good'

def populate_database():
    """Remplit la base de données sur 1 an"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    
    # Créer les tables d'abord
    print("🔄 Création du schéma...")
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS categories (
          id INTEGER PRIMARY KEY,
          name TEXT NOT NULL,
          emoji TEXT,
          description TEXT
        )
    ''')
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS kpis (
          id INTEGER PRIMARY KEY,
          category_id INTEGER NOT NULL,
          name TEXT NOT NULL,
          unit TEXT,
          target REAL,
          frequency TEXT,
          formula TEXT,
          description TEXT,
          FOREIGN KEY(category_id) REFERENCES categories(id)
        )
    ''')
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS measurements (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          kpi_id INTEGER NOT NULL,
          measurement_date DATETIME NOT NULL,
          value REAL NOT NULL,
          status TEXT,
          FOREIGN KEY(kpi_id) REFERENCES kpis(id)
        )
    ''')
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS alerts (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          kpi_id INTEGER NOT NULL,
          alert_type TEXT,
          severity TEXT,
          message TEXT,
          created_at DATETIME,
          FOREIGN KEY(kpi_id) REFERENCES kpis(id)
        )
    ''')
    
    # Supprimer les anciennes données
    cursor.execute('DELETE FROM measurements')
    cursor.execute('DELETE FROM alerts')
    cursor.execute('DELETE FROM kpis')
    cursor.execute('DELETE FROM categories')
    
    # Insérer les catégories
    for cat in CATEGORIES:
        cursor.execute(
            'INSERT INTO categories (id, name, emoji, description) VALUES (?, ?, ?, ?)',
            (cat['id'], cat['name'], cat['emoji'], cat['description'])
        )
    
    # Insérer les KPI
    for kpi in KPIS:
        cursor.execute(
            'INSERT INTO kpis (id, category_id, name, unit, target, frequency, formula, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
            (kpi['id'], kpi['category_id'], kpi['name'], kpi['unit'], kpi['target'], kpi['frequency'], kpi['formula'], kpi['description'])
        )
    
    # Générer les mesures sur 1 an
    end_date = datetime.now()
    start_date = end_date - timedelta(days=365)
    
    print("🔄 Génération des mesures sur 1 an...")
    measurements_count = 0
    
    for kpi in KPIS:
        kpi_id = kpi['id']
        target = kpi['target']
        frequency_minutes = get_frequency_minutes(kpi['frequency'])
        
        current_date = start_date
        while current_date <= end_date:
            value = generate_value(kpi_id, target)
            status = determine_status(kpi_id, value, target)
            
            cursor.execute(
                'INSERT INTO measurements (kpi_id, measurement_date, value, status) VALUES (?, ?, ?, ?)',
                (kpi_id, current_date.isoformat(), value, status)
            )
            measurements_count += 1
            
            current_date += timedelta(minutes=frequency_minutes)
    
    conn.commit()
    conn.close()
    
    print(f"✅ Base de données remplie avec succès!")
    print(f"📊 {measurements_count} mesures créées")
    print(f"🎯 {len(KPIS)} KPI configurés")
    print(f"📁 Fichier: {DB_PATH}")

if __name__ == '__main__':
    populate_database()
