"""
Script voor het ophalen van een HEEL JAAR aan historische weerdata voor Amersfoort
"""
import requests
import sqlite3
import pandas as pd
from datetime import datetime
import time

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

# Kies je jaar(en) hier!
START_JAAR = 2025
START_MAAND = 1
START_DAG = 1

EIND_JAAR = 2025
EIND_MAAND = 11
EIND_DAG = 11

DATABASE_NAAM = f"weer_amersfoort_{START_JAAR}.db"

# Open-Meteo kan maximaal 1 jaar per request, dus we splitsen het op indien nodig
# ========================

def setup_database(db_naam):
    """Maak database en tabellen aan"""
    conn = sqlite3.connect(db_naam)
    cursor = conn.cursor()
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS weer_dagelijks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            datum DATE UNIQUE NOT NULL,
            locatie TEXT NOT NULL,
            latitude REAL,
            longitude REAL,
            temp_max REAL,
            temp_min REAL,
            temp_gem REAL,
            neerslag REAL,
            wind_max REAL,
            wind_gem REAL,
            wind_richting REAL,
            luchtvochtigheid_gem REAL,
            bewolking_gem REAL,
            zonuren REAL,
            toegevoegd_op TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS weer_uurlijks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            datum_tijd DATETIME UNIQUE NOT NULL,
            locatie TEXT NOT NULL,
            temperatuur REAL,
            gevoelstemperatuur REAL,
            neerslag REAL,
            wind_snelheid REAL,
            wind_richting REAL,
            luchtvochtigheid INTEGER,
            bewolking INTEGER,
            luchtdruk REAL,
            toegevoegd_op TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    
    conn.commit()
    return conn

def haal_weerdata_op(start_date, end_date, ophaal_uurlijks=True):
    """
    Haal weerdata op via Open-Meteo API
    
    Args:
        start_date: datetime object voor startdatum
        end_date: datetime object voor einddatum
        ophaal_uurlijks: Ook uurlijkse data ophalen (kan veel data zijn!)
    """
    url = "https://archive-api.open-meteo.com/v1/archive"
    
    # Uitgebreide parameters voor een volledig beeld
    params = {
        "latitude": LATITUDE,
        "longitude": LONGITUDE,
        "start_date": start_date.strftime("%Y-%m-%d"),
        "end_date": end_date.strftime("%Y-%m-%d"),
        "daily": [
            "temperature_2m_max",
            "temperature_2m_min",
            "temperature_2m_mean",
            "apparent_temperature_max",
            "apparent_temperature_min",
            "precipitation_sum",
            "rain_sum",
            "snowfall_sum",
            "precipitation_hours",
            "wind_speed_10m_max",
            "wind_speed_10m_mean",
            "wind_direction_10m_dominant",
            "sunshine_duration"
        ],
        "timezone": "Europe/Amsterdam"
    }
    
    if ophaal_uurlijks:
        params["hourly"] = [
            "temperature_2m",
            "apparent_temperature",
            "precipitation",
            "rain",
            "snowfall",
            "wind_speed_10m",
            "wind_direction_10m",
            "relative_humidity_2m",
            "cloud_cover",
            "surface_pressure"
        ]
    
    print(f"\n📡 Data ophalen voor periode: {start_date.date()} tot {end_date.date()}")
    print(f"   Aantal dagen: {(end_date - start_date).days + 1}")
    
    try:
        response = requests.get(url, params=params, timeout=60)
        response.raise_for_status()
        print(f"✅ Data succesvol opgehaald!")
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"❌ Fout bij ophalen data: {e}")
        return None

def sla_dagelijkse_data_op(conn, data):
    """Sla dagelijkse data op in database"""
    if not data or 'daily' not in data:
        return 0
    
    daily = data['daily']
    cursor = conn.cursor()
    records_toegevoegd = 0
    
    for i in range(len(daily['time'])):
        try:
            cursor.execute('''
                INSERT OR REPLACE INTO weer_dagelijks 
                (datum, locatie, latitude, longitude, temp_max, temp_min, 
                 temp_gem, neerslag, wind_max, wind_gem, wind_richting,
                 zonuren)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                daily['time'][i],
                LOCATIE,
                LATITUDE,
                LONGITUDE,
                daily['temperature_2m_max'][i],
                daily['temperature_2m_min'][i],
                daily['temperature_2m_mean'][i],
                daily['precipitation_sum'][i],
                daily['wind_speed_10m_max'][i],
                daily['wind_speed_10m_mean'][i],
                daily['wind_direction_10m_dominant'][i],
                daily['sunshine_duration'][i] / 3600 if daily['sunshine_duration'][i] else None  # Convert seconds to hours
            ))
            records_toegevoegd += 1
        except sqlite3.IntegrityError:
            pass
    
    conn.commit()
    return records_toegevoegd

def sla_uurlijkse_data_op(conn, data):
    """Sla uurlijkse data op in database"""
    if not data or 'hourly' not in data:
        return 0
    
    hourly = data['hourly']
    cursor = conn.cursor()
    records_toegevoegd = 0
    
    print(f"   Uurlijkse records verwerken: {len(hourly['time'])} uur...")
    
    # Batch insert voor betere performance
    batch = []
    for i in range(len(hourly['time'])):
        batch.append((
            hourly['time'][i],
            LOCATIE,
            hourly['temperature_2m'][i],
            hourly['apparent_temperature'][i],
            hourly['precipitation'][i],
            hourly['wind_speed_10m'][i],
            hourly['wind_direction_10m'][i],
            hourly['relative_humidity_2m'][i],
            hourly['cloud_cover'][i],
            hourly['surface_pressure'][i]
        ))
    
    cursor.executemany('''
        INSERT OR REPLACE INTO weer_uurlijks 
        (datum_tijd, locatie, temperatuur, gevoelstemperatuur, neerslag, 
         wind_snelheid, wind_richting, luchtvochtigheid, bewolking, luchtdruk)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ''', batch)
    
    conn.commit()
    return len(batch)

def toon_statistieken(conn):
    """Toon statistieken van de database"""
    cursor = conn.cursor()
    
    cursor.execute("SELECT COUNT(*) FROM weer_dagelijks")
    aantal_dagen = cursor.fetchone()[0]
    
    cursor.execute("SELECT COUNT(*) FROM weer_uurlijks")
    aantal_uren = cursor.fetchone()[0]
    
    print("\n" + "="*70)
    print("DATABASE STATISTIEKEN")
    print("="*70)
    print(f"📊 Dagelijkse records: {aantal_dagen} dagen")
    print(f"📊 Uurlijkse records:  {aantal_uren} uur")
    
    if aantal_dagen > 0:
        cursor.execute("""
            SELECT 
                MIN(datum) as eerste_datum,
                MAX(datum) as laatste_datum,
                ROUND(AVG(temp_max), 1) as gem_max_temp,
                ROUND(MAX(temp_max), 1) as hoogste_temp,
                ROUND(MIN(temp_min), 1) as laagste_temp,
                ROUND(SUM(neerslag), 1) as totale_neerslag,
                ROUND(AVG(wind_max), 1) as gem_wind,
                ROUND(SUM(zonuren), 1) as totale_zonuren
            FROM weer_dagelijks
        """)
        
        stats = cursor.fetchone()
        print(f"\n📅 Periode: {stats[0]} tot {stats[1]}")
        print(f"\n🌡️  TEMPERATUUR:")
        print(f"   Gemiddeld max:      {stats[2]}°C")
        print(f"   Hoogste:            {stats[3]}°C")
        print(f"   Laagste:            {stats[4]}°C")
        print(f"\n💧 NEERSLAG:")
        print(f"   Totaal:             {stats[5]} mm")
        print(f"\n💨 WIND:")
        print(f"   Gemiddeld max:      {stats[6]} km/h")
        print(f"\n☀️  ZON:")
        print(f"   Totale zonuren:     {stats[7]} uur ({stats[7]/24:.1f} dagen)")
        
        # Maandstatistieken
        print(f"\n📊 PER MAAND:")
        cursor.execute("""
            SELECT 
                strftime('%Y-%m', datum) as maand,
                ROUND(AVG(temp_max), 1) as gem_max,
                ROUND(AVG(temp_min), 1) as gem_min,
                ROUND(SUM(neerslag), 1) as neerslag,
                COUNT(CASE WHEN neerslag > 0.1 THEN 1 END) as regendagen
            FROM weer_dagelijks
            GROUP BY maand
            ORDER BY maand
        """)
        
        print(f"\n   {'Maand':<10} {'Max°C':<8} {'Min°C':<8} {'Neerslag':<12} {'Regendagen':<12}")
        print(f"   {'-'*60}")
        for row in cursor.fetchall():
            print(f"   {row[0]:<10} {row[1]:<8} {row[2]:<8} {row[3]:<12} {row[4]:<12}")
    
    print("="*70)

def exporteer_naar_csv(conn, output_prefix="weer_export"):
    """Exporteer data naar CSV bestanden"""
    # Dagelijkse data
    df_dagelijks = pd.read_sql_query(
        "SELECT * FROM weer_dagelijks ORDER BY datum", 
        conn
    )
    csv_dag = f"{output_prefix}_dagelijks.csv"
    df_dagelijks.to_csv(csv_dag, index=False)
    print(f"✅ Dagelijkse data: {csv_dag} ({len(df_dagelijks)} records)")
    
    # Uurlijkse data (alleen als niet te groot)
    cursor = conn.cursor()
    cursor.execute("SELECT COUNT(*) FROM weer_uurlijks")
    aantal_uur = cursor.fetchone()[0]
    
    if aantal_uur > 0 and aantal_uur < 10000:  # Max ~1 jaar uurlijks
        df_uurlijks = pd.read_sql_query(
            "SELECT * FROM weer_uurlijks ORDER BY datum_tijd", 
            conn
        )
        csv_uur = f"{output_prefix}_uurlijks.csv"
        df_uurlijks.to_csv(csv_uur, index=False)
        print(f"✅ Uurlijkse data:  {csv_uur} ({len(df_uurlijks)} records)")
    elif aantal_uur > 10000:
        print(f"⚠️  Uurlijkse data ({aantal_uur} records) niet geëxporteerd (te groot)")


def main():
    """Hoofdfunctie"""
    print("="*70)
    print(f"HISTORISCHE WEERDATA VOOR {LOCATIE}")
    print("="*70)
    
    # Datum objecten maken
    start_date = datetime(START_JAAR, START_MAAND, START_DAG)
    end_date = datetime(EIND_JAAR, EIND_MAAND, EIND_DAG)
    
    # Check of periode niet te groot is
    dagen = (end_date - start_date).days + 1
    if dagen > 400:
        antwoord = input(f"\n⚠️  Je wilt {dagen} dagen ophalen. Dit kan even duren. Doorgaan? (j/n): ")
        if antwoord.lower() != 'j':
            print("Geannuleerd.")
            return
    
    # Uurlijkse data vraag
    if dagen > 180:
        print(f"\n💡 TIP: Voor {dagen} dagen is dat {dagen*24} uur aan data.")
        ophaal_uurlijks = input("   Wil je ook uurlijkse data? Dit maakt de database groter. (j/n): ")
        ophaal_uurlijks = ophaal_uurlijks.lower() == 'j'
    else:
        ophaal_uurlijks = True
    
    # Setup database
    print(f"\n📁 Database: {DATABASE_NAAM}")
    conn = setup_database(DATABASE_NAAM)
    
    # Haal data op
    data = haal_weerdata_op(start_date, end_date, ophaal_uurlijks)
    
    if data:
        print("\n💾 Data opslaan in database...")
        
        # Dagelijkse data
        dag_records = sla_dagelijkse_data_op(conn, data)
        print(f"✅ {dag_records} dagelijkse records opgeslagen")
        
        # Uurlijkse data
        if ophaal_uurlijks:
            uur_records = sla_uurlijkse_data_op(conn, data)
            print(f"✅ {uur_records} uurlijkse records opgeslagen")
        
        # Statistieken
        toon_statistieken(conn)
        
        # Exporteer
        print(f"\n📤 Data exporteren...")
        exporteer_naar_csv(conn, f"amersfoort_{START_JAAR}")
        
    conn.close()
    print(f"\n✅ Klaar! Database opgeslagen als: {DATABASE_NAAM}")


if __name__ == "__main__":
    print("\n💡 Open-Meteo API - Gratis historische weerdata")
    print("   Data beschikbaar vanaf 1940")
    print("   Geen API key nodig!\n")
    
    main()
