import xml.etree.ElementTree as ET
import mysql.connector
import time

# ---- CONFIGURATION ----
# 🔹 Connexion à la base de données MySQL
DB_CONFIG = {
    "host": "localhost",
    "port": "8889",
    "user": "root",
    "password": "root",
    "database": "vroomly-api"
}
XML_FILE = "/Users/petrusedgar/Downloads/PrixCarburants_quotidien_20250309.xml"  # Remplace par le chemin de ton fichier XML https://donnees.roulez-eco.fr/opendata/jour/AAAAMMJJ

# ---- CONNEXION À MYSQL ----
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()

# ---- CRÉATION DES TABLES ----
TABLES = {
    "pdv": """
        CREATE TABLE IF NOT EXISTS pdv (
            id INT PRIMARY KEY,
            latitude INT,
            longitude INT,
            cp VARCHAR(10),
            pop VARCHAR(5),
            adresse VARCHAR(255),
            ville VARCHAR(255)
        )
    """,
    "horaires": """
        CREATE TABLE IF NOT EXISTS horaires (
            pdv_id INT,
            jour VARCHAR(15),
            ferme BOOLEAN,
            FOREIGN KEY (pdv_id) REFERENCES pdv(id)
        )
    """,
    "services": """
        CREATE TABLE IF NOT EXISTS services (
            pdv_id INT,
            service VARCHAR(255),
            FOREIGN KEY (pdv_id) REFERENCES pdv(id)
        )
    """,
    "prix": """
        CREATE TABLE IF NOT EXISTS prix (
            pdv_id INT,
            carburant VARCHAR(10),
            maj DATETIME,
            valeur FLOAT,
            FOREIGN KEY (pdv_id) REFERENCES pdv(id)
        )
    """,
    "ruptures": """
        CREATE TABLE IF NOT EXISTS ruptures (
            pdv_id INT,
            carburant VARCHAR(10),
            debut DATETIME,
            fin DATETIME NULL,
            type VARCHAR(20),
            FOREIGN KEY (pdv_id) REFERENCES pdv(id)
        )
    """
}

def safe_int(value):
    try:
        return int(float(value))  # Convertit en float d'abord puis en int
    except ValueError:
        #print(f"❌ Erreur : Impossible de convertir {value} en int")
        return 0  # Retourne None en cas d'erreur

# Fonction pour insérer un service dans la base de données
def insert_service(service_name):
    sql = '''INSERT IGNORE INTO services(name) VALUES(%s)'''
    cursor.execute(sql, (service_name,))
    conn.commit()



#for table, query in TABLES.items():
#    cursor.execute(query)

# ---- PRÉCHARGEMENT DES ID DE CARBURANTS ----
cursor.execute("SELECT id, alias FROM carburant")
carburant_ids = {alias: id for id, alias in cursor.fetchall()}  # ✅ Évite les requêtes répétées

rupture_data = []

# ---- PARSING DU FICHIER XML ----
tree = ET.parse(XML_FILE)
root = tree.getroot()

start_time = time.time()  # ⏱ Début du chrono

# Insertion des services
# Extraire les services et les insérer dans la base de données
for pdv in root.findall('pdv'):
    for service in pdv.find('services').findall('service'):
        service_name = service.text.strip()
        insert_service(service_name)


for pdv in root.findall("pdv"):
    pdv_id = int(pdv.get("id"))
    latitude = int(safe_int(pdv.get("latitude")))/100000
    longitude = int(safe_int(pdv.get("longitude")))/100000
    cp = pdv.get("cp")
    pop = pdv.get("pop")
    adresse = pdv.find("adresse").text
    ville = pdv.find("ville").text

    # Insertion de la station-service
    #cursor.execute("""
    #    INSERT INTO pdv (id, latitude, longitude, cp, pop, adresse, ville)
    #    VALUES (%s, %s, %s, %s, %s, %s, %s)
    #    ON DUPLICATE KEY UPDATE latitude=VALUES(latitude), longitude=VALUES(longitude),
    #    cp=VALUES(cp), pop=VALUES(pop), adresse=VALUES(adresse), ville=VALUES(ville)
    #""", (pdv_id, latitude, longitude, cp, pop, adresse, ville))

    cursor.execute("""
    INSERT INTO station (id_station, name, latitude, longitude, postalcode, address, city)
    VALUES (%s, "Station - "%s, %s, %s, %s, %s, %s)
    ON DUPLICATE KEY UPDATE 
        latitude = VALUES(latitude), 
        longitude = VALUES(longitude),
        postalcode = VALUES(postalcode), 
        address = VALUES(address), 
        city = VALUES(city)
    """, (pdv_id, ville, latitude, longitude, cp, adresse, ville))

    # Insertion des horaires
    #horaires = pdv.find("horaires")
    #if horaires:
    #    for jour in horaires.findall("jour"):
    #        cursor.execute("""
    #            INSERT INTO horaires (station_id, day, closed)
    #            VALUES (%s, %s, %s)
    #        """, (pdv_id, jour.get("nom"), bool(int(jour.get("ferme")))))

# ---- COMMIT ET FERMETURE ----
conn.commit()

end_time = time.time()  # ⏱ Fin du chrono
elapsed_time = end_time - start_time  # ⏱ Calcul du temps

print(f"✅ Stations insérées avec succès en {elapsed_time:.2f}s !")

start_time = time.time()  # ⏱ Début du chrono

for pdv in root.findall("pdv"):
    pdv_id = int(pdv.get("id"))
    latitude = int(safe_int(pdv.get("latitude")))/100000
    longitude = int(safe_int(pdv.get("longitude")))/100000
    cp = pdv.get("cp")
    pop = pdv.get("pop")
    adresse = pdv.find("adresse").text
    ville = pdv.find("ville").text

    # Insertion des services
    services = pdv.find("services")
    if services:
        for service in services.findall("service"):
            cursor.execute("""
                INSERT INTO station_services (station_id, services_id)
                SELECT s.id, sv.id
                FROM station s
                JOIN services sv ON sv.name = %s
                WHERE s.id_station = %s;

            """, (service.text, pdv_id))

    
# ---- COMMIT ET FERMETURE ----
conn.commit()

end_time = time.time()  # ⏱ Fin du chrono
elapsed_time = end_time - start_time  # ⏱ Calcul du temps

print(f"✅ Services insérées avec succès en {elapsed_time:.2f}s !")

start_time = time.time()  # ⏱ Début du chrono

for pdv in root.findall("pdv"):
    pdv_id = int(pdv.get("id"))
    latitude = int(safe_int(pdv.get("latitude")))/100000
    longitude = int(safe_int(pdv.get("longitude")))/100000
    cp = pdv.get("cp")
    pop = pdv.get("pop")
    adresse = pdv.find("adresse").text
    ville = pdv.find("ville").text

    # Insertion des prix
    # Insertion des prix des carburants
    prix_elements = pdv.findall("prix")
    for prix in prix_elements:
        try:
            # Récupérer les informations nécessaires
            carburant_nom = prix.get("nom")
            prix_valeur = float(prix.get("valeur"))
            modified_at = prix.get("maj")  # Date de modification
            rupture = 0

            # Vérifier si l'attribut rupture existe, sinon utiliser une valeur par défaut
            #rupture = prix.get("rupture", 'Non')  # Valeur par défaut 'Non' si rupture n'existe pas

            # Exécuter l'insertion
            cursor.execute("""
                INSERT INTO carburantlist (carburant_id, station_id, price, modified_at, rupture)
                SELECT c.id, s.id, %s, %s, %s
                FROM station s
                JOIN carburant c ON c.alias = %s
                WHERE s.id_station = %s
            """, (prix_valeur, modified_at, rupture, carburant_nom, pdv_id))

            # Commit après chaque insertion si nécessaire
            conn.commit()
            
        except Error as e:
            print(f"Erreur lors de l'insertion du carburant '{carburant_nom}' pour la station {pdv_id}: {e}")

# ---- COMMIT ET FERMETURE ----
conn.commit()

end_time = time.time()  # ⏱ Fin du chrono
elapsed_time = end_time - start_time  # ⏱ Calcul du temps

print(f"✅ Prix insérés avec succès en {elapsed_time:.2f}s !")

start_time = time.time()  # ⏱ Début du chrono

for pdv in root.findall("pdv"):
    pdv_id = int(pdv.get("id"))
    latitude = int(safe_int(pdv.get("latitude")))/100000
    longitude = int(safe_int(pdv.get("longitude")))/100000
    cp = pdv.get("cp")
    pop = pdv.get("pop")
    adresse = pdv.find("adresse").text
    ville = pdv.find("ville").text

    # Insertion des ruptures
    # 🔹 Vérifier si la station existe
    cursor.execute("SELECT id FROM station WHERE id_station = %s", (pdv_id,))
    result = cursor.fetchone()
    
    if not result:
        print(f"⚠️ Station {pdv_id} non trouvée, rupture ignorée.")
        continue
    
    idStation = result[0]

    # 🔹 Insertion des ruptures
    for rupture in pdv.findall("rupture"):
        carburant_nom = rupture.get("nom")
        modified_at = rupture.get("debut")  # Date de début de rupture

        # Vérifier si le carburant existe
        carburant_id = carburant_ids.get(carburant_nom)
        if not carburant_id:
            print(f"⚠️ Carburant {carburant_nom} inconnu, rupture ignorée.")
            continue

        # Ajouter la requête à la liste
        rupture_data.append((idStation, carburant_id, modified_at))

        # ---- INSERT OU UPDATE DES RUPTURES ----
        if rupture_data:
            cursor.executemany("""
                INSERT INTO carburantlist (station_id, carburant_id, modified_at, rupture)
                VALUES (%s, %s, %s, 1)
                ON DUPLICATE KEY UPDATE 
                    modified_at = VALUES(modified_at), 
                    rupture = 1
            """, rupture_data)
            conn.commit()  # ✅ Un seul commit pour toutes les insertions/mises à jour


# ---- COMMIT ET FERMETURE ----
conn.commit()

end_time = time.time()  # ⏱ Fin du chrono
elapsed_time = end_time - start_time  # ⏱ Calcul du temps

print(f"✅ Ruptures insérées avec succès en {elapsed_time:.2f}s !")