"""BAN YARO — Service-Angebote (Sitting & Walks Matching)"""

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

router = APIRouter()

ALLOWED_TYPES = {'sitting', 'walks'}


def _haversine(lat1, lon1, lat2, lon2):
    R = 6371.0
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = (math.sin(dlat / 2) ** 2
         + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2))
         * math.sin(dlon / 2) ** 2)
    return R * 2 * math.asin(math.sqrt(a))


# ------------------------------------------------------------------
# Schemas
# ------------------------------------------------------------------
class ServiceCreate(BaseModel):
    type:          str
    beschreibung:  Optional[str]   = None
    preis_pro_tag: Optional[float] = None
    lat:           Optional[float] = None
    lon:           Optional[float] = None
    radius_km:     int             = 10


# ------------------------------------------------------------------
# GET /api/services — Angebote in der Nähe
# ------------------------------------------------------------------
@router.get("")
async def list_services(
    type:   str,
    lat:    Optional[float] = None,
    lon:    Optional[float] = None,
    radius: float           = 20,   # km
):
    if type not in ALLOWED_TYPES:
        raise HTTPException(400, f"type muss 'sitting' oder 'walks' sein.")

    with db() as conn:
        rows = conn.execute("""
            SELECT so.*, u.name AS anbieter_name
            FROM service_offers so
            JOIN users u ON u.id = so.user_id
            WHERE so.type = ? AND so.aktiv = 1
            LIMIT 200
        """, (type,)).fetchall()

    result = []
    for r in rows:
        d = dict(r)
        if lat is not None and lon is not None and d['lat'] and d['lon']:
            dist = _haversine(lat, lon, d['lat'], d['lon'])
            if dist > radius:
                continue
            d['distanz_km'] = round(dist, 1)
        else:
            d['distanz_km'] = None
        result.append(d)

    if lat is not None:
        result.sort(key=lambda x: x.get('distanz_km') or 9999)

    return result[:50]


# ------------------------------------------------------------------
# GET /api/services/me — eigene Angebote
# ------------------------------------------------------------------
@router.get("/me")
async def my_services(user=Depends(get_current_user)):
    with db() as conn:
        rows = conn.execute(
            "SELECT * FROM service_offers WHERE user_id = ? ORDER BY type",
            (user['id'],)
        ).fetchall()
    return [dict(r) for r in rows]


# ------------------------------------------------------------------
# POST /api/services — Angebot erstellen oder aktualisieren (Upsert)
# ------------------------------------------------------------------
@router.post("", status_code=201)
async def upsert_service(data: ServiceCreate, user=Depends(get_current_user)):
    if data.type not in ALLOWED_TYPES:
        raise HTTPException(400, "type muss 'sitting' oder 'walks' sein.")

    with db() as conn:
        existing = conn.execute(
            "SELECT id FROM service_offers WHERE user_id = ? AND type = ?",
            (user['id'], data.type)
        ).fetchone()

        if existing:
            conn.execute("""
                UPDATE service_offers
                SET beschreibung = ?, preis_pro_tag = ?, lat = ?, lon = ?,
                    radius_km = ?, aktiv = 1
                WHERE user_id = ? AND type = ?
            """, (data.beschreibung, data.preis_pro_tag, data.lat, data.lon,
                  data.radius_km, user['id'], data.type))
            row = conn.execute(
                "SELECT * FROM service_offers WHERE user_id = ? AND type = ?",
                (user['id'], data.type)
            ).fetchone()
        else:
            cur = conn.execute("""
                INSERT INTO service_offers
                    (user_id, type, beschreibung, preis_pro_tag, lat, lon, radius_km)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            """, (user['id'], data.type, data.beschreibung, data.preis_pro_tag,
                  data.lat, data.lon, data.radius_km))
            row = conn.execute(
                "SELECT * FROM service_offers WHERE id = ?", (cur.lastrowid,)
            ).fetchone()

    return dict(row)


# ------------------------------------------------------------------
# DELETE /api/services/{id} — Angebot deaktivieren
# ------------------------------------------------------------------
@router.delete("/{offer_id}")
async def deactivate_service(offer_id: int, user=Depends(get_current_user)):
    with db() as conn:
        offer = conn.execute(
            "SELECT * FROM service_offers WHERE id = ?", (offer_id,)
        ).fetchone()
        if not offer:
            raise HTTPException(404, "Angebot nicht gefunden.")
        if offer['user_id'] != user['id']:
            raise HTTPException(403, "Kein Zugriff.")
        conn.execute(
            "UPDATE service_offers SET aktiv = 0 WHERE id = ?", (offer_id,)
        )
    return {"ok": True}
