"""BAN YARO — Verlorener Hund Routes"""

import os, uuid, math
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
from pydantic import BaseModel
from typing import Optional
from database import db
from auth import get_current_user
from timeutils import safe_client_time
from routes.push import send_push_to_all
from media_utils import convert_media

router    = APIRouter()
MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")


# ------------------------------------------------------------------
# Haversine-Distanz in Metern
# ------------------------------------------------------------------
def _haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
    R  = 6_371_000
    p1 = math.radians(lat1)
    p2 = math.radians(lat2)
    dp = math.radians(lat2 - lat1)
    dl = math.radians(lon2 - lon1)
    a  = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2
    return 2 * R * math.asin(math.sqrt(a))


# ------------------------------------------------------------------
# Schemas
# ------------------------------------------------------------------
class LostDogCreate(BaseModel):
    name:         str
    rasse:        Optional[str] = None
    beschreibung: str
    lat:          float
    lon:          float
    dog_id:       Optional[int] = None
    client_time:  Optional[str] = None


# ------------------------------------------------------------------
# GET /api/lost — aktive Meldungen (optional nach Distanz gefiltert)
# ------------------------------------------------------------------
@router.get("")
async def list_lost(lat: Optional[float] = None, lon: Optional[float] = None,
                    radius_km: float = 25):
    with db() as conn:
        rows = conn.execute(
            """SELECT l.*, u.name AS melder_name
               FROM   lost_dogs l
               LEFT JOIN users u ON u.id = l.user_id
               WHERE  l.is_active = 1
               ORDER  BY l.created_at DESC"""
        ).fetchall()

    results = []
    for r in rows:
        entry = dict(r)
        if lat is not None and lon is not None:
            dist = _haversine(lat, lon, entry["lat"], entry["lon"])
            if dist > radius_km * 1000:
                continue
            entry["distanz_m"] = round(dist)
        results.append(entry)

    if lat is not None and lon is not None:
        results.sort(key=lambda x: x.get("distanz_m", 0))

    return results


# ------------------------------------------------------------------
# POST /api/lost — Hund vermisst melden (Login erforderlich)
# ------------------------------------------------------------------
@router.post("", status_code=201)
async def report_lost(data: LostDogCreate, user=Depends(get_current_user)):
    with db() as conn:
        ct = safe_client_time(data.client_time)
        conn.execute(
            """INSERT INTO lost_dogs (user_id, dog_id, name, rasse, beschreibung, lat, lon, created_at)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
            (user["id"], data.dog_id, data.name, data.rasse,
             data.beschreibung, data.lat, data.lon, ct)
        )
        row = conn.execute(
            "SELECT * FROM lost_dogs WHERE user_id=? ORDER BY id DESC LIMIT 1",
            (user["id"],)
        ).fetchone()
    entry = dict(row)

    send_push_to_all({
        "type":  "lost_dog_alert",
        "title": f"🔍 {data.name} wird vermisst!",
        "body":  f"{data.rasse or 'Hund'} in deiner Nähe vermisst. Hilf bei der Suche!",
        "tag":   f"lost-{entry['id']}",
        "data":  {"page": "lost"},
    })

    return entry


# ------------------------------------------------------------------
# POST /api/lost/{id}/foto — Foto hochladen (Login, eigene Meldung)
# ------------------------------------------------------------------
@router.post("/{lost_id}/foto")
async def upload_foto(
    lost_id: int,
    file: UploadFile = File(...),
    user=Depends(get_current_user),
):
    with db() as conn:
        entry = conn.execute(
            "SELECT id FROM lost_dogs WHERE id=? AND user_id=?",
            (lost_id, user["id"])
        ).fetchone()
    if not entry:
        raise HTTPException(404, "Meldung nicht gefunden oder keine Berechtigung.")

    data, ext = convert_media(await file.read(), file.filename or "")
    if not ext:
        ext = ".jpg"
    filename = f"lost_{lost_id}_{uuid.uuid4().hex[:8]}{ext}"
    path     = os.path.join(MEDIA_DIR, "lost", filename)
    os.makedirs(os.path.dirname(path), exist_ok=True)

    with open(path, "wb") as f:
        f.write(data)

    foto_url = f"/media/lost/{filename}"
    with db() as conn:
        conn.execute("UPDATE lost_dogs SET foto_url=? WHERE id=?", (foto_url, lost_id))

    return {"foto_url": foto_url}


# ------------------------------------------------------------------
# POST /api/lost/{id}/found — als gefunden markieren (Login, eigene Meldung)
# ------------------------------------------------------------------
@router.post("/{lost_id}/found")
async def mark_found(lost_id: int, user=Depends(get_current_user)):
    with db() as conn:
        entry = conn.execute(
            "SELECT * FROM lost_dogs WHERE id=?", (lost_id,)
        ).fetchone()
        if not entry:
            raise HTTPException(404, "Meldung nicht gefunden.")
        e = dict(entry)
        if e["user_id"] != user["id"] and user.get("rolle") != "admin":
            raise HTTPException(403, "Keine Berechtigung.")
        conn.execute(
            """UPDATE lost_dogs
               SET    is_active=0, gefunden_at=datetime('now')
               WHERE  id=?""",
            (lost_id,)
        )
    return {"ok": True}


# ------------------------------------------------------------------
# DELETE /api/lost/{id} — eigene Meldung löschen (Login)
# ------------------------------------------------------------------
@router.delete("/{lost_id}", status_code=204)
async def delete_lost(lost_id: int, user=Depends(get_current_user)):
    with db() as conn:
        entry = conn.execute(
            "SELECT * FROM lost_dogs WHERE id=?", (lost_id,)
        ).fetchone()
        if not entry:
            raise HTTPException(404, "Meldung nicht gefunden.")
        e = dict(entry)
        if e["user_id"] != user["id"] and user.get("rolle") != "admin":
            raise HTTPException(403, "Keine Berechtigung.")
        conn.execute("DELETE FROM lost_dogs WHERE id=?", (lost_id,))
    return None
