#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Générateur de cartes météo professionnelles pour la Basse-Normandie
Style TV moderne avec fond beige et icônes météo réalistes
Utilise l'API Open-Meteo (gratuite, sans clé API)
"""

import os
import sys
from datetime import datetime, timedelta
from pathlib import Path
import re

import openmeteo_requests
from PIL import Image
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from matplotlib.patches import Rectangle, FancyBboxPatch
import matplotlib.patheffects as path_effects
from scipy import ndimage
import numpy as np

try:
    import geopandas as gpd
    HAS_GEOPANDAS = True
except ImportError:
    HAS_GEOPANDAS = False
    print("⚠️  geopandas non disponible")

# Villes de Basse-Normandie
VILLES_BASSE_NORMANDIE = {
    "Cherbourg": {"lat": 49.6337, "lon": -1.6167, "importance": 1},
    "Caen": {"lat": 49.1829, "lon": -0.3707, "importance": 1},
    "Alençon": {"lat": 48.4322, "lon": 0.0913, "importance": 1},
    "Saint-Lô": {"lat": 49.1167, "lon": -1.0833, "importance": 2},
    "Lisieux": {"lat": 49.1461, "lon": 0.2256, "importance": 2},
    "Avranches": {"lat": 48.65, "lon": -1.3500, "importance": 2},
    "Vire": {"lat": 48.8400, "lon": -0.8894, "importance": 2},
    "Flers": {"lat": 48.7500, "lon": -0.5667, "importance": 2},
    "L'Aigle": {"lat": 48.7651, "lon": 0.6278, "importance": 2},
    "Argentan": {"lat": 48.7428, "lon": -0.0223, "importance": 2},
    "Lessay": {"lat": 49.2132, "lon": -1.5202, "importance": 2},
    "Bellême": {"lat": 48.3753, "lon": 0.5629, "importance": 2},
    "Bayeux": {"lat": 49.2564, "lon": -0.7024, "importance": 2},
}

# Positions supplémentaires (icône météo uniquement, sans nom ni température)
POSITIONS_ICONES_SEULES = {
    "Montebourg": {"lat": 49.4882, "lon": -1.3808},
    "Bricquebec": {"lat": 49.4716, "lon": -1.7028},
    "Coutances": {"lat": 49.0477, "lon": -1.4454},
    "Gavray": {"lat": 48.9101, "lon": -1.3499},
    "Potigny": {"lat": 49.0093, "lon": -0.2608},
    "Mortain": {"lat": 48.6474, "lon": -0.9424},
    "Domfront": {"lat": 48.5913, "lon": -0.6487},
    "Aunay sur Odon": {"lat": 49.0178, "lon": -0.6308},
    "Crevecoeur en Auge": {"lat": 49.10, "lon": -0.0313},
    "Rânes": {"lat": 48.6716, "lon": -0.3047},
    "Le Sap": {"lat": 48.8971, "lon": 0.3123},
    "Le Merlerault": {"lat": 48.6941, "lon": 0.2841},
    "Bretoncelles": {"lat": 48.4296, "lon": 0.8895},
    "Cabourg": {"lat": 49.3023, "lon": -0.0793},
    "Honfleur": {"lat": 49.4194, "lon": 0.2335},
}

# Départements
DEPT_BASSE_NORMANDIE = ["14", "50", "61"]  # Calvados, Manche, Orne
DEPT_VOISINS = ["35", "53", "72", "28", "27", "76", "41", "22", "56"]  # Ille-et-Vilaine, Mayenne, Sarthe, Eure-et-Loir, Eure, Seine-Maritime

# Noms des départements voisins
DEPT_NAMES = {
    "35": "ILLE-ET-VILAINE", "53": "MAYENNE", "72": "SARTHE",
    "28": "EURE-ET-LOIR", "27": "EURE", "76": "SEINE-MARITIME", "41": "LOIR-ET-CHER", "22": "COTES D'ARMOR", "56": "MORBIHAN"
}

# Positions pour les flèches de vent (points d'intérêt sur la carte)
WIND_POSITIONS = [
    {"name": "Côte Nord", "lat": 49.6, "lon": -1.4},
    {"name": "Large Cherbourg", "lat": 49.7, "lon": -1.8},
    {"name": "Baie du Mont", "lat": 48.7, "lon": -1.5},
    {"name": "Côte Est", "lat": 49.35, "lon": 0.07},
    {"name": "Centre Manche", "lat": 49.0, "lon": -1.2},
    {"name": "Bocage", "lat": 48.8, "lon": -0.73},
    {"name": "Perche", "lat": 48.3, "lon": 0.7},
    {"name": "Marais de Carentan", "lat": 49.4, "lon": -1.3},
    {"name": "Isigny", "lat": 49.36, "lon": -1},
    {"name": "Orne", "lat": 48.8, "lon": -0.3},
    {"name": "Manche", "lat": 49.11, "lon": -0.87},
    {"name": "Perche 2", "lat": 48.60, "lon": 0.80},
    {"name": "Sud Calvados", "lat": 48.95, "lon": 0.10},
]

# Mapping codes météo WMO vers icônes locales
# WMO Weather interpretation codes (WW) - Standard international
METEO_TO_ICON = {
    0: "ensoleille-big.png",  # Ciel dégagé
    1: "faibles-passages-nuageux-big.png",  # Principalement dégagé
    2: "eclaircies-big.png",  # Partiellement nuageux
    3: "faiblement-nuageux-big.png",  # Couvert
    45: "brouillard-big.png",  # Brouillard
    48: "brouillard-big.png",  # Brouillard givrant
    51: "pluie-faible-big.png",  # Bruine légère
    53: "pluie-faible-big.png",  # Bruine modérée
    55: "pluie-moderee-big.png",  # Bruine dense
    56: "pluie-et-neige-melee-faible-big.png",  # Bruine verglaçante légère
    57: "pluie-et-neige-melee-moderee-big.png",  # Bruine verglaçante dense
    61: "pluie-faible-big.png",  # Pluie légère
    63: "pluie-moderee-big.png",  # Pluie modérée
    65: "pluie-forte-big.png",  # Pluie forte
    66: "pluie-et-neige-melee-faible-big.png",  # Pluie verglaçante légère
    67: "pluie-et-neige-melee-forte-big.png",  # Pluie verglaçante forte
    71: "neige-faible-big.png",  # Chute de neige légère
    73: "neige-moderee-big.png",  # Chute de neige modérée
    75: "neige-forte-big.png",  # Chute de neige forte
    77: "averses-de-neige-faible-big.png",  # Grains de neige
    80: "averses-de-pluie-faible-big.png",  # Averses de pluie légères
    81: "averses-de-pluie-faible-big.png",  # Averses de pluie modérées
    82: "averses-de-pluie-forte-big.png",  # Averses de pluie violentes
    85: "averses-de-neige-faible-big.png",  # Averses de neige légères
    86: "averses-de-neige-faible-big.png",  # Averses de neige fortes
    95: "orage-modere-big.png",  # Orage léger ou modéré
    96: "fortement-orageux-big.png",  # Orage avec grêle légère
    99: "fortement-orageux-big.png",  # Orage avec grêle forte
}

ICON_CACHE = {}
WIND_ICON_CACHE = {}


def load_local_icon(icon_filename, size=80):
    """Charge une icône locale depuis le dossier /icones"""
    if icon_filename in ICON_CACHE:
        return ICON_CACHE[icon_filename]
    
    icons_dir = Path(os.environ.get("ICONS_DIR", "./icones"))
    icon_path = icons_dir / icon_filename
    
    try:
        if icon_path.exists():
            img = Image.open(icon_path).convert("RGBA")
            img = img.resize((size, size), Image.LANCZOS)
            ICON_CACHE[icon_filename] = img
            return img
        else:
            print(f"    ⚠️  Icône non trouvée: {icon_path}")
    except Exception as e:
        print(f"    ⚠️  Erreur chargement icône {icon_filename}: {e}")
    return None


def load_wind_icon(wind_speed):
    """Charge l'icône de vent appropriée selon la vitesse"""
    # Déterminer quelle icône utiliser selon la vitesse
    if wind_speed < 30:
        icon_name = "directionbok.png"  # Bleu - vent faible
    elif wind_speed < 60:
        icon_name = "directionjok.png"  # Jaune - vent modéré
    else:
        icon_name = "directionrok.png"  # Rouge - vent fort
    
    cache_key = icon_name
    if cache_key in WIND_ICON_CACHE:
        return WIND_ICON_CACHE[cache_key]
    
    wind_icons_dir = Path(os.environ.get("WIND_ICONS_DIR", "./vent"))
    icon_path = wind_icons_dir / icon_name
    
    try:
        if icon_path.exists():
            img = Image.open(icon_path).convert("RGBA")
            # Redimensionner à une taille plus petite
            img = img.resize((50, 50), Image.LANCZOS)
            WIND_ICON_CACHE[cache_key] = img
            return img
        else:
            print(f"    ⚠️  Icône vent non trouvée: {icon_path}")
    except Exception as e:
        print(f"    ⚠️  Erreur chargement icône vent: {e}")
    return None


def rotate_image(image, angle):
    """Fait pivoter une image PIL"""
    return image.rotate(angle, expand=True, resample=Image.BICUBIC)


def get_forecast_for_city(client, city_name, city_data, target_date):
    """Récupère les prévisions Open-Meteo pour une ville avec données horaires"""
    try:
        url = "https://api.open-meteo.com/v1/forecast"
        params = {
            "latitude": city_data["lat"],
            "longitude": city_data["lon"],
            "hourly": ["temperature_2m", "weather_code", "wind_speed_10m", "wind_direction_10m"],
            "timezone": "Europe/Paris",
            "forecast_days": 7
        }
        
        responses = client.weather_api(url, params=params)
        response = responses[0]
        
        # Extraire les données horaires
        hourly = response.Hourly()
        hourly_time = hourly.Time()
        temp_values = hourly.Variables(0).ValuesAsNumpy()
        weather_code_values = hourly.Variables(1).ValuesAsNumpy()
        wind_speed_values = hourly.Variables(2).ValuesAsNumpy()
        wind_direction_values = hourly.Variables(3).ValuesAsNumpy()
        
        # Trouver les heures correspondantes pour la date cible
        target_date_start = target_date.replace(hour=0, minute=0, second=0, microsecond=0)
        
        # Indices pour matin (6h-12h) et après-midi (12h-18h)
        morning_temps = []
        morning_codes = []
        morning_wind_speeds = []
        morning_wind_dirs = []
        afternoon_temps = []
        afternoon_codes = []
        afternoon_wind_speeds = []
        afternoon_wind_dirs = []
        
        for i in range(len(temp_values)):
            hour_timestamp = hourly_time + i * 3600  # Ajouter i heures en secondes
            hour_datetime = datetime.fromtimestamp(hour_timestamp)
            
            if hour_datetime.date() == target_date.date():
                hour = hour_datetime.hour
                
                # Matin: 6h à 11h59
                if 6 <= hour < 12:
                    morning_temps.append(temp_values[i])
                    morning_codes.append(weather_code_values[i])
                    morning_wind_speeds.append(wind_speed_values[i])
                    morning_wind_dirs.append(wind_direction_values[i])
                
                # Après-midi: 12h à 17h59
                elif 12 <= hour < 18:
                    afternoon_temps.append(temp_values[i])
                    afternoon_codes.append(weather_code_values[i])
                    afternoon_wind_speeds.append(wind_speed_values[i])
                    afternoon_wind_dirs.append(wind_direction_values[i])
        
        if morning_temps and afternoon_temps:
            # Utiliser la température moyenne et le code météo le plus fréquent
            morning_code = int(np.bincount([int(c) for c in morning_codes]).argmax())
            afternoon_code = int(np.bincount([int(c) for c in afternoon_codes]).argmax())
            
            return {
                "morning": {
                    "temp": float(np.mean(morning_temps)),
                    "weather_code": morning_code,
                    "wind_speed": float(np.mean(morning_wind_speeds)),
                    "wind_direction": float(np.mean(morning_wind_dirs))
                },
                "afternoon": {
                    "temp": float(np.mean(afternoon_temps)),
                    "weather_code": afternoon_code,
                    "wind_speed": float(np.mean(afternoon_wind_speeds)),
                    "wind_direction": float(np.mean(afternoon_wind_dirs))
                }
            }
        
        return None
    except Exception as e:
        print(f"  ❌ Erreur {city_name}: {e}")
        import traceback
        traceback.print_exc()
        return None


def parse_weather_string(s):
    """Parse une chaîne de code météo"""
    if s is None:
        return 0
    if isinstance(s, int):
        return s
    numbers = re.findall(r'\d+', str(s))
    return int(numbers[0]) if numbers else 0


def extract_weather_code(weather_data):
    """Extrait le code météo"""
    if weather_data is None:
        return 0
    if isinstance(weather_data, int):
        return weather_data
    if isinstance(weather_data, dict):
        return parse_weather_string(weather_data.get("icon", weather_data.get("code", "0")))
    return parse_weather_string(weather_data)

def draw_wind_arrow(ax, x, y, direction, speed, zorder=15):
    """Dessine une flèche de vent avec icône pivotée selon la direction"""
    # Ne rien afficher si la vitesse est négative, nulle ou très faible
    if speed <= 0:
        return
    
    # Charger l'icône appropriée
    wind_icon = load_wind_icon(speed)
    
    if wind_icon:
        # Les icônes sont orientées SUD (180°)
        # Direction météo: d'où vient le vent (0° = Nord)
        rotation_angle = direction  # La direction indique d'où vient le vent
        
        # Pivoter l'icône
        rotated_icon = rotate_image(wind_icon, -rotation_angle)
        
        # Afficher l'icône pivotée (réduite)
        imagebox = OffsetImage(np.array(rotated_icon), zoom=0.5)
        ab = AnnotationBbox(imagebox, (x, y), frameon=False, zorder=zorder)
        ax.add_artist(ab)
        
        # Ajouter la vitesse AU CENTRE de l'icône (à l'intérieur)
        speed_kmh = int(speed)
        ax.text(x, y, f"{speed_kmh}", fontsize=8, fontweight='bold',
               ha='center', va='center', color='white', zorder=zorder+2,
               path_effects=[path_effects.withStroke(linewidth=2, foreground='black')])

def extract_forecast_data(forecast, target_date, period="morning"):
    """Extrait les données de prévision pour une période"""
    if not forecast:
        return None
    
    # Les données sont maintenant séparées par période
    period_data = forecast.get(period)
    if not period_data:
        return None
    
    return {
        "temp_min": period_data.get("temp"),
        "temp_max": period_data.get("temp"),
        "weather": period_data.get("weather_code", 0),
        "wind_speed": period_data.get("wind_speed", 0),
        "wind_direction": period_data.get("wind_direction", 0),
    }


def create_weather_map(forecasts, target_date, period, output_path, geojson_path):
    """Crée une carte météo style TV professionnelle"""
    
    # Couleurs style carte TV - plus proches du modèle
    COLOR_BG = '#e8dcc8'  # Beige plus clair
    COLOR_NORMANDIE = '#f5ead8'  # Beige très clair pour la Basse-Normandie
    COLOR_VOISINS = '#d4c4a8'  # Beige-gris pour départements voisins
    COLOR_MER = '#0f37a8'  # Bleu marine pour la mer
    COLOR_BORDURE = '#8b8680'  # Gris beige pour les bordures
    
    # Figure sans espace supplémentaire
    fig = plt.figure(figsize=(14, 10), facecolor=COLOR_BG)
    ax = fig.add_axes([0.02, 0.02, 0.96, 0.96])
    ax.set_facecolor(COLOR_MER)
    
    # Limites élargies pour voir toute la Basse-Normandie + voisins
    ax.set_xlim(-2.3, 1.2)
    ax.set_ylim(48.0, 49.9)
    ax.set_aspect('equal')
    
    # Charger le GeoJSON
    if HAS_GEOPANDAS and os.path.exists(geojson_path):
        try:
            gdf = gpd.read_file(geojson_path)
            
            # Dessiner les départements voisins (gris)
            voisins = gdf[gdf['code'].isin(DEPT_VOISINS)]
            voisins.plot(ax=ax, color=COLOR_VOISINS, edgecolor=COLOR_BORDURE, 
                        linewidth=0.8, alpha=0.95, zorder=2)
            
            # Ajouter les noms des départements voisins
            for idx, row in voisins.iterrows():
                centroid = row.geometry.centroid
                name = DEPT_NAMES.get(row['code'], '')
                if name and ax.get_xlim()[0] < centroid.x < ax.get_xlim()[1]:
                    ax.text(centroid.x, centroid.y, name, fontsize=7, 
                           ha='center', va='center', color='#6b6b6b',
                           style='italic', alpha=0.6, zorder=3)
            
            # Dessiner la Basse-Normandie (beige clair)
            normandie = gdf[gdf['code'].isin(DEPT_BASSE_NORMANDIE)]
            normandie.plot(ax=ax, color=COLOR_NORMANDIE, edgecolor=COLOR_BORDURE,
                          linewidth=1.2, alpha=1, zorder=4)
            
            # Bordures internes entre départements normands plus subtiles
            normandie.boundary.plot(ax=ax, color=COLOR_BORDURE, linewidth=0.5, 
                                   alpha=0.4, zorder=5)
            
        except Exception as e:
            print(f"  ⚠️  Erreur GeoJSON: {e}")
    
    # Label "LA MANCHE" pour la mer - 2 positions
    # Position centrale
    ax.text(-0.5, 49.45, "LA MANCHE", fontsize=12, fontweight='normal',
           ha='center', va='center', color='#7a9bb5', style='italic', 
           alpha=0.7, zorder=6)
    
    # Position à gauche (Baie du Mont-Saint-Michel)
    ax.text(-1.95, 49.20, "LA MANCHE", fontsize=12, fontweight='normal',
           ha='center', va='center', color='#7a9bb5', style='italic', 
           alpha=0.7, zorder=6)
    
    # Afficher les données météo
    for city_name, city_data in VILLES_BASSE_NORMANDIE.items():
        if city_name not in forecasts or forecasts[city_name] is None:
            continue
        
        data = forecasts[city_name]
        x, y = city_data["lon"], city_data["lat"]
        importance = city_data["importance"]
        
        temp = data.get("temp_max") if period == "afternoon" else data.get("temp_min")
        weather_code = data.get("weather", 0)
        icon_filename = METEO_TO_ICON.get(weather_code, "eclaircies-big.png")
        
        # Tailles uniformes pour toutes les villes
        icon_size = 80
        font_city = 11
        font_temp = 14  # Taille uniforme pour toutes les températures
        
        # Couleur du panneau température selon la période
        if period == "morning":
            temp_bg_color = '#1e3a8a'  # Bleu foncé pour le matin
        else:
            temp_bg_color = '#b91c1c'  # Rouge foncé pour l'après-midi
        
        # Icône météo - position rapprochée
        icon_img = load_local_icon(icon_filename, icon_size)
        if icon_img:
            imagebox = OffsetImage(np.array(icon_img), zoom=0.75)
            ab = AnnotationBbox(imagebox, (x, y + 0.04), frameon=False, zorder=20)
            ax.add_artist(ab)
        
        # Panneau nom de ville style panneau routier (blanc avec bordure rouge)
        bbox_city = dict(boxstyle='round,pad=0.3', facecolor='white', 
                        edgecolor='#DC143C', linewidth=2.5, alpha=1)
        ax.text(x, y + 0.13, city_name.upper(), fontsize=font_city, fontweight='bold',
               ha='center', va='center', color='black', bbox=bbox_city, zorder=25)
        
        # Panneau température - position sous l'icône, bien rapprochée
        if temp is not None:
            temp_str = f"{temp:.0f}°"
            bbox_temp = dict(boxstyle='round,pad=0.35', facecolor=temp_bg_color,
                           edgecolor='white', linewidth=2, alpha=0.95)
            ax.text(x, y - 0.06, temp_str, fontsize=font_temp, fontweight='bold',
                   ha='center', va='center', color='white', bbox=bbox_temp, zorder=25)
    
    # Afficher les icônes météo seules (sans nom ni température) pour les positions supplémentaires
    for city_name, city_data in POSITIONS_ICONES_SEULES.items():
        if city_name not in forecasts or forecasts[city_name] is None:
            continue
        
        data = forecasts[city_name]
        x, y = city_data["lon"], city_data["lat"]
        
        weather_code = data.get("weather", 0)
        icon_filename = METEO_TO_ICON.get(weather_code, "eclaircies-big.png")
        
        # Icône météo uniquement (taille moyenne)
        icon_size = 80
        icon_img = load_local_icon(icon_filename, icon_size)
        if icon_img:
            imagebox = OffsetImage(np.array(icon_img), zoom=0.75)
            ab = AnnotationBbox(imagebox, (x, y), frameon=False, zorder=20)
            ax.add_artist(ab)
    
    # Ajouter les flèches de vent aux positions définies
    # Utiliser les données de la première ville pour avoir des infos de vent
    first_city_forecast = next((f for f in forecasts.values() if f), None)
    if first_city_forecast:
        wind_speed = first_city_forecast.get("wind_speed", 20)
        wind_direction = first_city_forecast.get("wind_direction", 270)
        
        for wind_pos in WIND_POSITIONS:
            draw_wind_arrow(ax, wind_pos["lon"], wind_pos["lat"], 
                          wind_direction + np.random.randint(-30, 30),  # Variation
                          wind_speed + np.random.randint(-10, 10))  # Variation
    
    # Logo en haut à droite
    logo_path = Path(os.environ.get("LOGO_FILE", "./logo.png"))
    if logo_path.exists():
        try:
            logo_img = Image.open(logo_path).convert("RGBA")
            # Redimensionner le logo (hauteur max 100px)
            logo_height = 150
            logo_ratio = logo_height / logo_img.height
            logo_width = int(logo_img.width * logo_ratio)
            logo_img = logo_img.resize((logo_width, logo_height), Image.LANCZOS)
            
            # Positionner en haut à droite
            imagebox = OffsetImage(np.array(logo_img), zoom=1.0)
            ab = AnnotationBbox(imagebox, (0.80, 49.5), frameon=False, 
                               xycoords='data', zorder=35)
            ax.add_artist(ab)
        except Exception as e:
            print(f"    ⚠️  Erreur chargement logo: {e}")
    
    # Date de prévision AU-DESSUS du titre
    # Forcer le français pour les noms de jours et mois
    jour_semaine = {
        'Monday': 'lundi', 'Tuesday': 'mardi', 'Wednesday': 'mercredi',
        'Thursday': 'jeudi', 'Friday': 'vendredi', 'Saturday': 'samedi', 'Sunday': 'dimanche'
    }
    mois = {
        'January': 'janvier', 'February': 'février', 'March': 'mars', 'April': 'avril',
        'May': 'mai', 'June': 'juin', 'July': 'juillet', 'August': 'août',
        'September': 'septembre', 'October': 'octobre', 'November': 'novembre', 'December': 'décembre'
    }
    
    jour_en = target_date.strftime('%A')
    mois_en = target_date.strftime('%B')
    jour_fr = jour_semaine.get(jour_en, jour_en.lower())
    mois_fr = mois.get(mois_en, mois_en.lower())
    
    date_str_long = f"{jour_fr} {target_date.day} {mois_fr} {target_date.year}"
    
    ax.text(-0.40, 49.82, f"Prévisions pour la journée du {date_str_long}", 
            fontsize=10, ha='center', va='center', color='white', 
            style='italic', fontweight='bold', zorder=30,
            bbox=dict(boxstyle='round,pad=0.25', facecolor='#1a2a4a', 
                     edgecolor='white', linewidth=1.5, alpha=0.9))
    
    # Titre DANS la mer (en dessous de la date)
    period_title = "MATIN" if period == "morning" else "APRÈS-MIDI"
    period_time = "à 09h00." if period == "morning" else "à 15h00."
    
    # Grand titre stylisé positionné dans la zone mer (sous la date)
    ax.text(-0.40, 49.70, period_title, fontsize=28, fontweight='bold',
            ha='center', va='center', color='white', style='italic',
            bbox=dict(boxstyle='round,pad=0.4', facecolor='#1a2a4a', 
                     edgecolor='white', linewidth=2.5, alpha=0.95),
            zorder=30)
    
    # Sous-titre avec heure juste en dessous
    ax.text(-0.40, 49.60, f"prévisions météo {period_time}", fontsize=10,
            ha='center', va='center', color='white', style='italic',
            zorder=30)
    
    # Masquer les axes
    ax.set_xticks([])
    ax.set_yticks([])
    for spine in ax.spines.values():
        spine.set_visible(False)
    
    # Sauvegarder
    plt.savefig(output_path, dpi=150, bbox_inches='tight',
                facecolor=COLOR_BG, edgecolor='none', pad_inches=0.05)
    plt.close()
    
    print(f"  ✅ Carte générée: {output_path}")


def main():
    """Fonction principale"""
    print("\n" + "="*60)
    print("🌤️   MÉTÉO BASSE-NORMANDIE - STYLE TV PRO")
    print("="*60 + "\n")
    
    output_dir = Path(os.environ.get("OUTPUT_DIR", "./meteo_cartes"))
    output_dir.mkdir(parents=True, exist_ok=True)
    geojson_path = output_dir / "departements.geojson"
    
    tomorrow = datetime.now() + timedelta(days=1)
    
    try:
        import locale
        locale.setlocale(locale.LC_TIME, 'fr_FR.UTF-8')
    except:
        pass
    
    print(f"📅 Prévisions pour: {tomorrow.strftime('%A %d %B %Y')}\n")
    
    print("🔌 Connexion à Open-Meteo API...")
    try:
        client = openmeteo_requests.Client()
    except Exception as e:
        print(f"❌ Erreur: {e}")
        sys.exit(1)
    
    print("\n📍 Récupération des prévisions:\n")
    
    forecasts_morning = {}
    forecasts_afternoon = {}
    
    # Récupérer les prévisions pour les villes principales
    for city_name, city_data in VILLES_BASSE_NORMANDIE.items():
        print(f"  🏙️  {city_name}...", end=" ", flush=True)
        forecast = get_forecast_for_city(client, city_name, city_data, tomorrow)
        if forecast:
            forecasts_morning[city_name] = extract_forecast_data(forecast, tomorrow, "morning")
            forecasts_afternoon[city_name] = extract_forecast_data(forecast, tomorrow, "afternoon")
            print("✓")
        else:
            print("✗")
    
    # Récupérer les prévisions pour les positions icônes seules
    for city_name, city_data in POSITIONS_ICONES_SEULES.items():
        print(f"  📍 {city_name}...", end=" ", flush=True)
        forecast = get_forecast_for_city(client, city_name, city_data, tomorrow)
        if forecast:
            forecasts_morning[city_name] = extract_forecast_data(forecast, tomorrow, "morning")
            forecasts_afternoon[city_name] = extract_forecast_data(forecast, tomorrow, "afternoon")
            print("✓")
        else:
            print("✗")
    
    print("\n🎨 Génération des cartes:\n")
    
    date_str = tomorrow.strftime("%Y-%m-%d")
    
    morning_path = output_dir / f"meteo_basse_normandie_{date_str}_matin.png"
    create_weather_map(forecasts_morning, tomorrow, "morning", morning_path, geojson_path)
    
    afternoon_path = output_dir / f"meteo_basse_normandie_{date_str}_apres_midi.png"
    create_weather_map(forecasts_afternoon, tomorrow, "afternoon", afternoon_path, geojson_path)
    
    print("\n" + "="*60)
    print("✨ Terminé!")
    print(f"📁 Fichiers: {output_dir.absolute()}")
    print("="*60 + "\n")


if __name__ == "__main__":
    main()
