import asyncio
import httpx
import redis

from backend.database.session import SessionLocal
from backend.database.repositories import upsert_alert
from backend.schemas.alert import Alert

from backend.state.engine import set as save_state
from backend.discord.router import route
from backend.discord.lifecycle import publish_discord


REDIS = redis.Redis(host="localhost", port=6379, decode_responses=True)

NWS_URL = "https://api.weather.gov/alerts/active"

SEEN_KEY = "echoweather:seen_alerts"


def normalize(feature: dict) -> Alert:
    props = feature["properties"]

    return Alert(
        id=props["id"],
        event=props.get("event", "Unknown"),
        category=(props.get("event") or "unknown").lower(),
        tier=(props.get("severity") or "normal").lower(),
        headline=props.get("headline"),
        description=props.get("description"),
        instruction=props.get("instruction"),
        effective=props.get("effective"),
        expires=props.get("expires"),
        affected_counties=(props.get("areaDesc", "") or "").split(", "),
        population=None,
        homes=None,
        hospitals=None,
        schools=None,
        radar_indicated="radar" in (props.get("description") or "").lower(),
        confirmed="confirmed" in (props.get("description") or "").lower(),
    )


async def fetch():
    async with httpx.AsyncClient(timeout=30) as client:
        r = await client.get(NWS_URL)
        r.raise_for_status()
        return r.json()


async def run():
    print("[EchoWeather] NWS feed started (STABLE MODE)")

    while True:
        try:
            data = await fetch()
            features = data.get("features", [])

            with SessionLocal() as db:
                for f in features:
                    alert = normalize(f)

                    # ------------------------
                    # GLOBAL DEDUPE (REDIS)
                    # ------------------------
                    if REDIS.sismember(SEEN_KEY, alert.id):
                        continue

                    REDIS.sadd(SEEN_KEY, alert.id)

                    # ------------------------
                    # SAVE STATE
                    # ------------------------
                    upsert_alert(db, alert)
                    db.commit()

                    save_state(alert.model_dump())

                    # ------------------------
                    # ROUTE + DISCORD SEND
                    # ------------------------
                    channel = route(alert)
                    publish_discord(alert, channel)

                    print(f"[NEW ALERT] {alert.event} -> {channel}")

        except Exception as e:
            print("[FEED ERROR]", str(e))

        await asyncio.sleep(30)


if __name__ == "__main__":
    asyncio.run(run())
