"""BAN YARO — Tierärzte Routes (user-level, nie löschen)"""

import math
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from typing import Optional
from database import db
from auth import get_current_user

router = APIRouter()


class TierarztCreate(BaseModel):
    name:             str
    strasse:          Optional[str]   = None
    plz:              Optional[str]   = None
    ort:              Optional[str]   = None
    telefon:          Optional[str]   = None
    notfall_telefon:  Optional[str]   = None
    email:            Optional[str]   = None
    website:          Optional[str]   = None
    notizen:          Optional[str]   = None
    ist_notfallpraxis: bool           = False
    opening_hours:    Optional[str]   = None
    lat:              Optional[float] = None
    lon:              Optional[float] = None
    osm_id:           Optional[str]   = None


class TierarztUpdate(BaseModel):
    name:             Optional[str]   = None
    strasse:          Optional[str]   = None
    plz:              Optional[str]   = None
    ort:              Optional[str]   = None
    telefon:          Optional[str]   = None
    notfall_telefon:  Optional[str]   = None
    email:            Optional[str]   = None
    website:          Optional[str]   = None
    notizen:          Optional[str]   = None
    ist_notfallpraxis: Optional[bool] = None
    aktiv:            Optional[bool]  = None
    opening_hours:    Optional[str]   = None
    lat:              Optional[float] = None
    lon:              Optional[float] = None
    osm_id:           Optional[str]   = None


def _fmt_opening_hours(raw: str | None) -> str | None:
    """Wandelt OSM-opening_hours-String in lesbares Deutsch um.

    Beispiel: "Mo-Fr 08:00-18:00; Sa 09:00-13:00"
    → "Mo–Fr 08:00–18:00 · Sa 09:00–13:00"
    """
    if not raw:
        return None
    if raw.strip().lower() == "24/7":
        return "24/7 geöffnet"
    result = raw.replace(" - ", "–").replace("-", "–", 1)
    result = "; ".join(
        part.strip().replace(";", "").replace(",", " · ")
        for part in raw.split(";")
    )
    return result


@router.get("/my-favorite")
async def get_my_favorite(user=Depends(get_current_user)):
    """Favoriten-Tierarzt des Users (oder null)."""
    with db() as conn:
        row = conn.execute(
            """SELECT t.* FROM tieraerzte t
               JOIN favorite_vets fv ON fv.vet_id = t.id
               WHERE fv.user_id = ?
               LIMIT 1""",
            (user["id"],)
        ).fetchone()
    if not row:
        return None
    return dict(row)


@router.post("/{vet_id}/favorite")
async def toggle_favorite(vet_id: int, user=Depends(get_current_user)):
    """Tierarzt als Favorit setzen oder entfernen (toggle). Gibt {is_favorite: bool} zurück."""
    with db() as conn:
        vet = conn.execute(
            "SELECT id FROM tieraerzte WHERE id=?", (vet_id,)
        ).fetchone()
        if not vet:
            raise HTTPException(404, "Tierarzt nicht gefunden.")

        existing = conn.execute(
            "SELECT 1 FROM favorite_vets WHERE user_id=? AND vet_id=?",
            (user["id"], vet_id)
        ).fetchone()

        if existing:
            conn.execute(
                "DELETE FROM favorite_vets WHERE user_id=? AND vet_id=?",
                (user["id"], vet_id)
            )
            return {"is_favorite": False}
        else:
            conn.execute(
                "INSERT INTO favorite_vets (user_id, vet_id) VALUES (?, ?)",
                (user["id"], vet_id)
            )
            return {"is_favorite": True}


@router.get("")
async def list_tieraerzte(user=Depends(get_current_user)):
    """Alle Tierärzte des Users — aktive zuerst, dann inaktive. Enthält is_favorite."""
    with db() as conn:
        rows = conn.execute(
            "SELECT * FROM tieraerzte WHERE user_id=? ORDER BY aktiv DESC, name",
            (user["id"],)
        ).fetchall()
        favs = {r["vet_id"] for r in conn.execute(
            "SELECT vet_id FROM favorite_vets WHERE user_id=?", (user["id"],)
        ).fetchall()}
    result = []
    for r in rows:
        d = dict(r)
        d["is_favorite"] = r["id"] in favs
        result.append(d)
    return result


@router.get("/osm-nearby")
async def osm_nearby(
    lat: float = Query(...),
    lon: float = Query(...),
    radius_km: float = Query(5.0),
    user=Depends(get_current_user)
):
    """Findet Tierarzt-POIs aus dem OSM-Cache in der Nähe (max. 10 Treffer)."""
    with db() as conn:
        rows = conn.execute(
            """SELECT osm_id, name, lat, lon, opening_hours, phone, website
               FROM osm_pois
               WHERE type = 'tierarzt'
                 AND lat BETWEEN ? AND ?
                 AND lon BETWEEN ? AND ?""",
            (lat - radius_km / 111.0, lat + radius_km / 111.0,
             lon - radius_km / 111.0, lon + radius_km / 111.0)
        ).fetchall()

    def _dist(r):
        dlat = (r["lat"] - lat) * math.pi / 180
        dlon = (r["lon"] - lon) * math.pi / 180
        a = math.sin(dlat/2)**2 + math.cos(lat*math.pi/180) * math.cos(r["lat"]*math.pi/180) * math.sin(dlon/2)**2
        return 6371 * 2 * math.asin(math.sqrt(a))

    results = []
    for r in rows:
        d = _dist(r)
        if d <= radius_km:
            results.append({
                "osm_id":        r["osm_id"],
                "name":          r["name"],
                "lat":           r["lat"],
                "lon":           r["lon"],
                "opening_hours": r["opening_hours"],
                "opening_hours_fmt": _fmt_opening_hours(r["opening_hours"]),
                "phone":         r["phone"],
                "website":       r["website"],
                "distanz_km":    round(d, 2),
            })

    results.sort(key=lambda x: x["distanz_km"])
    return results[:10]


@router.post("", status_code=201)
async def create_tierarzt(data: TierarztCreate, user=Depends(get_current_user)):
    with db() as conn:
        conn.execute(
            """INSERT INTO tieraerzte
               (user_id, name, strasse, plz, ort, telefon, notfall_telefon,
                email, website, notizen, ist_notfallpraxis,
                opening_hours, lat, lon, osm_id)
               VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
            (user["id"], data.name, data.strasse, data.plz, data.ort,
             data.telefon, data.notfall_telefon, data.email, data.website,
             data.notizen, int(data.ist_notfallpraxis),
             data.opening_hours, data.lat, data.lon, data.osm_id)
        )
        row = conn.execute(
            "SELECT * FROM tieraerzte WHERE user_id=? ORDER BY id DESC LIMIT 1",
            (user["id"],)
        ).fetchone()
    return dict(row)


@router.patch("/{tierarzt_id}")
async def update_tierarzt(tierarzt_id: int, data: TierarztUpdate,
                           user=Depends(get_current_user)):
    with db() as conn:
        entry = conn.execute(
            "SELECT id FROM tieraerzte WHERE id=? AND user_id=?",
            (tierarzt_id, user["id"])
        ).fetchone()
        if not entry:
            raise HTTPException(404, "Tierarzt nicht gefunden.")

        updates = {k: v for k, v in data.model_dump().items() if v is not None}
        if "ist_notfallpraxis" in updates:
            updates["ist_notfallpraxis"] = int(updates["ist_notfallpraxis"])
        if "aktiv" in updates:
            updates["aktiv"] = int(updates["aktiv"])
        if not updates:
            row = conn.execute("SELECT * FROM tieraerzte WHERE id=?", (tierarzt_id,)).fetchone()
            return dict(row)

        set_clause = ", ".join(f"{k}=?" for k in updates)
        conn.execute(
            f"UPDATE tieraerzte SET {set_clause} WHERE id=?",
            list(updates.values()) + [tierarzt_id]
        )
        row = conn.execute("SELECT * FROM tieraerzte WHERE id=?", (tierarzt_id,)).fetchone()
    return dict(row)
