"""
Script voor het INCREMENTEEL ophalen van weerdata voor Amersfoort
en dit direct in MySQL op te slaan (met 'Upsert' logica).
Het vult de database aan vanaf de laatst bekende datum tot NU.
"""
import requests
import mysql.connector
from mysql.connector import Error
import pandas as pd
from datetime import datetime, timedelta
import time

# ===== CONFIGURATIE =====
LOCATIE = "Amersfoort"
LATITUDE = 52.15
LONGITUDE = 5.39

# --- MySQL Database Config ---
# VUL DIT IN MET JOUW GEGEVENS
DB_CONFIG = {
    'host': '192.168.178.201',
    'user': 'energy_prices_user',
    'password': 'kS9R*xp17ZwCD@CV&E^N',
    'database': 'energy_prices',
    'port': 3307
}
# ========================


def haal_recente_weerdata_op(aantal_dagen_terug):
    """
    Haal recente/huidige weerdata op via de Open-Meteo FORECAST API
    """
    url = "https://api.open-meteo.com/v1/forecast" # Dit is de Forecast API
    
    params = {
        "latitude": LATITUDE,
        "longitude": LONGITUDE,
        "hourly": [
            "temperature_2m",
            "apparent_temperature",
            "precipitation",
            "wind_speed_10m",
            "wind_direction_10m",
            "relative_humidity_2m",
            "cloud_cover",
            "surface_pressure",
            "shortwave_radiation"  
        ],
        "timezone": "Europe/Amsterdam",
        "past_days": int(aantal_dagen_terug) # Vraag data op van de afgelopen X dagen
    }
    
    print(f"\n📡 Data ophalen voor de afgelopen {aantal_dagen_terug} dagen (tot nu)...")
    
    try:
        response = requests.get(url, params=params, timeout=60)
        response.raise_for_status()
        print(f"✅ Data succesvol opgehaald van Open-Meteo!")
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"❌ Fout bij ophalen data: {e}")
        return None

def parse_api_data(data):
    """Converteer de JSON response van de Forecast API naar een DataFrame"""
    hourly = data['hourly']
    
    df = pd.DataFrame({
        "datum_tijd": pd.to_datetime(hourly['time']),
        "locatie": LOCATIE,
        "temperatuur": hourly['temperature_2m'],
        "gevoelstemperatuur": hourly['apparent_temperature'],
        "neerslag": hourly['precipitation'],
        "wind_snelheid": hourly['wind_speed_10m'],
        "wind_richting": hourly['wind_direction_10m'],
        "luchtvochtigheid": hourly['relative_humidity_2m'],
        "bewolking": hourly['cloud_cover'],
        "luchtdruk": hourly['surface_pressure'],
        "zonnestraling": hourly['shortwave_radiation']  
    })
    # Vervang 'None' of 'NaN' door None (dat MySQL als NULL begrijpt)
    df = df.where(pd.notnull(df), None)
    return df


def sla_data_op_mysql(conn, data_df):
    """Sla data op in MySQL database met 'Upsert' logica"""
    if data_df.empty:
        print("Geen data om op te slaan.")
        return 0
    
    cursor = conn.cursor()
    
    print(f" ----------------------------------------------------------------------")
    print(f"   {len(data_df)} uurlijkse records voor MySQL verwerken (Upsert)...")
    
    # Maak een lijst van tuples voor de 'executemany'
    batch = [tuple(row) for row in data_df.itertuples(index=False)]
    
    # De "Upsert" query. 
    # Dit werkt perfect omdat 'datum_tijd' je PRIMARY KEY is.
    query = """
    INSERT INTO amersfoort_weer_uurlijks 
    (datum_tijd, locatie, temperatuur, gevoelstemperatuur, neerslag, 
     wind_snelheid, wind_richting, luchtvochtigheid, bewolking, luchtdruk, zonnestraling)
    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
    ON DUPLICATE KEY UPDATE
        locatie = VALUES(locatie),
        temperatuur = VALUES(temperatuur),
        gevoelstemperatuur = VALUES(gevoelstemperatuur),
        neerslag = VALUES(neerslag),
        wind_snelheid = VALUES(wind_snelheid),
        wind_richting = VALUES(wind_richting),
        luchtvochtigheid = VALUES(luchtvochtigheid),
        bewolking = VALUES(bewolking),
        luchtdruk = VALUES(luchtdruk),
        zonnestraling = VALUES(zonnestraling);
    """
    
    try:
        cursor.executemany(query, batch)
        conn.commit()
        
        # rowcount bij 'upsert' telt 1 voor een INSERT, en 2 voor een UPDATE
        print(f"✅ {cursor.rowcount} records succesvol verwerkt (inserted/updated).")
        return cursor.rowcount
    except Error as e:
        print(f"❌ Fout bij opslaan naar MySQL: {e}")
        conn.rollback()
        return 0

def main():
    """Hoofdfunctie"""
    print("="*70)
    print(f"INCREMENTELE WEERDATA UPDATE VOOR {LOCATIE} -> MYSQL")
    print("="*70)
    
    conn = None
    try:
        # 1. Verbind met DB en vind laatste datum
        print("💾 Verbinden met MySQL database...")
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        print("✅ Succesvol verbonden met MySQL.")
        
        cursor.execute("SELECT MAX(datum_tijd) FROM amersfoort_weer_uurlijks")
        result = cursor.fetchone()
        last_date_in_db = result[0] if result[0] else None

        aantal_dagen_terug = 1
        if last_date_in_db is None:
            print("Database is leeg. 16 dagen data wordt opgehaald.")
            aantal_dagen_terug = 16 # Maximaal wat de API toestaat
        else:
            print(f"Laatste datum in database: {last_date_in_db}")
            # Bereken hoeveel dagen we terug moeten kijken
            # +1 voor veiligheid, +1 omdat 'past_days' geen 'vandaag' meerekent
            dagen_verschil = (datetime.now() - last_date_in_db).days + 2
            aantal_dagen_terug = min(max(1, dagen_verschil), 16) 
            
            print(f"Database is {dagen_verschil-2} dagen oud. We halen {aantal_dagen_terug} dag(en) op.")

        # 2. Haal recente data op
        data = haal_recente_weerdata_op(aantal_dagen_terug)
        
        if data:
            # 3. Parse de data naar een DataFrame
            all_data_df = parse_api_data(data)
            
            # 4. Filter ALLEEN de data die we nog niet hebben
            # We filteren alle data *na* de laatste datum in de DB
            """ if last_date_in_db is not None:
                # We pakken alle data *na* onze laatste meting
                # De 'upsert' query handelt eventuele overlap af
                data_om_op_te_slaan = all_data_df[all_data_df['datum_tijd'] > last_date_in_db].copy()
            else:
                data_om_op_te_slaan = all_data_df.copy() # Alles is nieuw """
            
            # 4. Stuur *alle* opgehaalde data naar MySQL.
            # De 'ON DUPLICATE KEY' query regelt de updates en inserts.
            data_om_op_te_slaan = all_data_df.copy()

            # 5. Sla de data op
            if not data_om_op_te_slaan.empty:
                sla_data_op_mysql(conn, data_om_op_te_slaan)
            else:
                print("\n✅ Je database is al volledig up-to-date.")

    except Error as e:
        print(f"❌ Hoofdfout: {e}")
    finally:
        if conn and conn.is_connected():
            conn.close()
            print("Verbinding met MySQL gesloten.")
    
    print(f"\n✅ Klaar! Script voltooid.")


if __name__ == "__main__":
    main()