#!/usr/bin/env python3

import os
import sys
import json
import gi
import requests
from datetime import datetime, timezone

gi.require_version('Geoclue', '2.0')
from gi.repository import Geoclue

# ─────────── ICONOS DEL CLIMA ─────────── #
weather_icons = {
    "01d": "", "01n": "", "02d": "", "02n": "",
    "03d": "", "03n": "", "04d": "", "04n": "",
    "09d": "", "09n": "", "10d": "", "10n": "",
    "11d": "", "11n": "", "13d": "", "13n": "",
    "50d": "", "50n": "", "default": ""
}

# ─────────── API KEYS ─────────── #
try:
    with open('/home/teraflops/apikeys/openweathermaps', 'r') as f:
        api_key = f.read().strip()
    with open('/home/teraflops/apikeys/google_geoip', 'r') as f:
        google_key = f.read().strip()
except Exception:
    print(json.dumps({"text": "Error al leer las API keys"}))
    sys.exit(1)

# ─────────── OBTENER UBICACIÓN ─────────── #
def get_location_from_geoclue():
    try:
        clue = Geoclue.Simple.new_sync("weather-script", Geoclue.AccuracyLevel.EXACT, None)
        location = clue.get_location()
        lat = location.get_property('latitude')
        lon = location.get_property('longitude')
        desc = location.get_property('description')
        acc = location.get_property('accuracy')
        print(f"🛰️ GeoClue: {lat}, {lon} — Precisión: {acc:.1f} m — Fuente: {desc}")
        return lat, lon, desc
    except Exception as e:
        print("GeoClue (GI): error al obtener ubicación:", e)
        return None

def get_location_from_google():
    try:
        url = f"https://www.googleapis.com/geolocation/v1/geolocate?key={google_key}"
        response = requests.post(url, json={})
        response.raise_for_status()
        data = response.json()
        lat = data['location']['lat']
        lon = data['location']['lng']
        accuracy = data.get('accuracy', 0)
        print(f"🛰️ GoogleGeo: {lat}, {lon} — Precisión: {accuracy:.0f} m")
        return lat, lon, f"GoogleGeo ({accuracy:.0f} m)"
    except Exception as e:
        print("Google Geolocation API: fallo:", e)
        return None

def reverse_geocode(lat, lon):
    try:
        url = "https://nominatim.openstreetmap.org/reverse"
        params = {
            "lat": lat,
            "lon": lon,
            "format": "json",
            "zoom": 10,
            "addressdetails": 1,
        }
        headers = {"User-Agent": "weather-waybar-script"}
        response = requests.get(url, params=params, headers=headers)
        response.raise_for_status()
        data = response.json()
        address = data.get("address", {})
        ciudad = address.get("city") or address.get("town") or address.get("village") or "Desconocido"
        pais = address.get("country", "Desconocido")
        return ciudad, pais
    except Exception as e:
        print("Reverse geocode falló:", e)
        return "Desconocido", "Desconocido"

# ─────────── ALERTA LLUVIA SOLO EN TOOLTIP ─────────── #
def check_rain_alert(forecast_data, threshold=60, max_horas=6):
    ahora = datetime.utcnow()
    mensaje_alerta = ""

    for block in forecast_data['list']:
        bloque_hora = datetime.strptime(block['dt_txt'], "%Y-%m-%d %H:%M:%S")
        if bloque_hora <= ahora:
            continue

        if (bloque_hora - ahora).total_seconds() > max_horas * 3600:
            continue

        pop = block.get('pop', 0) * 100
        if pop >= threshold:
            hora_local = bloque_hora.replace(tzinfo=timezone.utc).astimezone().strftime("%H:%M")
            mensaje_alerta = f"⚠️ Posible lluvia a las {hora_local} ({int(pop)}%)"
            break

    return mensaje_alerta

# ─────────── PRONÓSTICO EXTENDIDO ─────────── #
def get_daily_forecast(forecast_data):
    from collections import defaultdict
    dias = defaultdict(list)
    for entry in forecast_data['list']:
        fecha = entry['dt_txt'].split(' ')[0]
        dias[fecha].append(entry)

    resumen = []
    for i, (dia, bloques) in enumerate(dias.items()):
        if i >= 3: break
        temps = [b['main']['temp'] for b in bloques]
        pops = [b.get('pop', 0) * 100 for b in bloques]
        estado = bloques[0]['weather'][0]['description'].capitalize()
        resumen.append(f"📅 {dia}: {estado}, {round(min(temps))}–{round(max(temps))}°C, ☔ {round(max(pops))}%")
    return "\n".join(resumen)

# ─────────── UBICACIÓN ─────────── #
usar_ubicacion_manual = False  # Cambia a True si quieres forzar ubicación

if usar_ubicacion_manual:
    latitud, longitud = 40.4168, -3.7038  # Ejemplo: Madrid
    region = "Manual"
    print(f"🧪 Usando ubicación manual: {latitud}, {longitud}")
else:
    loc = get_location_from_geoclue() or get_location_from_google()
    if not loc:
        print(json.dumps({"text": "Error al obtener la ubicación"}))
        sys.exit(1)
    latitud, longitud, region = loc

ciudad, pais = reverse_geocode(latitud, longitud)

# ─────────── API WEATHER ─────────── #
params = {
    "lat": latitud,
    "lon": longitud,
    "appid": api_key,
    "units": "metric",
    "lang": "es",
}

weather_url = "https://api.openweathermap.org/data/2.5/weather"
response = requests.get(weather_url, params=params)
if response.status_code != 200:
    print(json.dumps({"text": "Error al obtener datos del clima"}))
    sys.exit(1)
data = response.json()

# ─────────── DATOS CLIMA ─────────── #
temp = f"{round(data['main']['temp'])}°C"
status = data['weather'][0]['description'].capitalize()
status_code = data['weather'][0]['icon']
icon = weather_icons.get(status_code, weather_icons["default"])
temp_feel = f"{round(data['main']['feels_like'])}°C"
temp_feel_text = f"Sensación de {temp_feel}"
temp_min = f"{round(data['main']['temp_min'])}°C"
temp_max = f"{round(data['main']['temp_max'])}°C"
temp_min_max = f" {temp_min}\t\t {temp_max}"
wind_speed = f"{round(data['wind']['speed'] * 3.6)} km/h"
wind_text = f" {wind_speed}"
humidity = f"{data['main']['humidity']}%"
humidity_text = f" {humidity}"
visibility = data.get('visibility', 0)
visibility_km = f"{visibility / 1000} km"
visibility_text = f" {visibility_km}"

# ─────────── CALIDAD DEL AIRE ─────────── #
aqi_url = "https://api.openweathermap.org/data/2.5/air_pollution"
aqi_response = requests.get(aqi_url, params=params)
if aqi_response.status_code == 200:
    aqi = aqi_response.json()['list'][0]['main']['aqi']
    aqi_levels = {1: "Bueno", 2: "Moderado", 3: "Perjudicial", 4: "Malo", 5: "Muy malo"}
    air_quality_index = aqi_levels.get(aqi, "N/A")
else:
    air_quality_index = "N/A"

# ─────────── PRONÓSTICO ─────────── #
forecast_url = "https://api.openweathermap.org/data/2.5/forecast"
forecast_response = requests.get(forecast_url, params=params)
if forecast_response.status_code == 200:
    forecast_data = forecast_response.json()
    precipitation = forecast_data['list'][0].get('pop', 0) * 100
    prediction = f"\n\n    {precipitation:.0f}% probabilidad de lluvia"
    alerta_lluvia = check_rain_alert(forecast_data)
    pronostico_dias = get_daily_forecast(forecast_data)
else:
    prediction = ""
    alerta_lluvia = ""
    pronostico_dias = ""

# ─────────── TOOLTIP ─────────── #
time_of_day = "Día" if status_code.endswith('d') else "Noche"
ubicacion = f"{ciudad}, {region}, {pais} ({latitud:.2f}, {longitud:.2f})"

tooltip_text = ""
if alerta_lluvia:
    tooltip_text += f"{alerta_lluvia}\n\n"

tooltip_text += str.format(
    "{}\n{}\n{}\n{}\n\n{}\n{}\n{}{}\n\n<small>{}</small>",
    f'<span size="xx-large">{temp}</span>',
    f"<big>{icon}</big>",
    f"<big>{status} ({time_of_day})</big>",
    f"<small>{temp_feel_text}</small>",
    f"<big>{temp_min_max}</big>",
    f"{wind_text}\t{humidity_text}",
    f"{visibility_text}\tICA {air_quality_index}",
    f"<i>{prediction}</i>",
    f"Ubicación: {ubicacion}"
)

if pronostico_dias:
    tooltip_text += f"\n\n<b>Próximos días:</b>\n{pronostico_dias}"

# ─────────── OUTPUT PARA WAYBAR ─────────── #
out_data = {
    "text": f"{icon} {temp}",
    "alt": f"{status} ({time_of_day})",
    "tooltip": tooltip_text,
    "class": status_code,
}

print(json.dumps(out_data))

