"""BAN YARO — Freundschaften"""
import logging
from fastapi import APIRouter, Depends, HTTPException
from database import db
from auth import get_current_user

router = APIRouter()
logger = logging.getLogger(__name__)


def _dogs_subquery():
    """JSON-Array der Hunde eines Users als Subquery."""
    return """(
        SELECT json_group_array(json_object(
            'id',      d.id,
            'name',    d.name,
            'rasse',   d.rasse,
            'foto_url',d.foto_url
        ))
        FROM dogs d WHERE d.user_id = u.id
    )"""


@router.get("/")
async def list_friends(user=Depends(get_current_user)):
    uid = user["id"]
    dogs_sq = _dogs_subquery()
    with db() as conn:
        friends = conn.execute(f"""
            SELECT f.id, f.status, f.created_at,
                   CASE WHEN f.requester_id=? THEN f.addressee_id ELSE f.requester_id END AS friend_id,
                   u.name AS friend_name,
                   u.bio, u.wohnort, u.erfahrung, u.social_link,
                   u.profil_sichtbarkeit, u.avatar_url,
                   u.is_founder, u.is_partner, u.founder_number,
                   {dogs_sq} AS dogs_json
            FROM friendships f
            JOIN users u ON u.id = CASE WHEN f.requester_id=? THEN f.addressee_id ELSE f.requester_id END
            WHERE (f.requester_id=? OR f.addressee_id=?) AND f.status='accepted'
            ORDER BY u.name
        """, (uid, uid, uid, uid)).fetchall()

        incoming = conn.execute(f"""
            SELECT f.id, f.created_at, u.name AS requester_name, u.id AS requester_id,
                   u.avatar_url,
                   {dogs_sq} AS dogs_json
            FROM friendships f
            JOIN users u ON u.id=f.requester_id
            WHERE f.addressee_id=? AND f.status='pending'
            ORDER BY f.created_at DESC
        """, (uid,)).fetchall()

        outgoing = conn.execute("""
            SELECT f.id, f.created_at, u.name AS addressee_name, u.id AS addressee_id
            FROM friendships f
            JOIN users u ON u.id=f.addressee_id
            WHERE f.requester_id=? AND f.status='pending'
            ORDER BY f.created_at DESC
        """, (uid,)).fetchall()

    import json

    def _parse(rows):
        result = []
        for r in rows:
            d = dict(r)
            if d.get("dogs_json"):
                try:
                    d["dogs"] = json.loads(d["dogs_json"])
                except Exception:
                    d["dogs"] = []
            else:
                d["dogs"] = []
            d.pop("dogs_json", None)
            result.append(d)
        return result

    return {
        "friends":  _parse(friends),
        "incoming": _parse(incoming),
        "outgoing": [dict(r) for r in outgoing],
    }


@router.get("/search")
async def search_users(q: str = "", user=Depends(get_current_user)):
    if len(q.strip()) < 2:
        return []
    uid = user["id"]
    import json
    with db() as conn:
        rows = conn.execute("""
            SELECT u.id, u.name,
                   u.bio, u.wohnort, u.erfahrung, u.social_link,
                   u.profil_sichtbarkeit, u.avatar_url,
                   u.is_founder, u.is_partner, u.founder_number,
                   (SELECT json_group_array(json_object('name', d.name, 'rasse', d.rasse))
                    FROM dogs d WHERE d.user_id=u.id AND d.is_public=1) AS dogs_json
            FROM users u
            WHERE u.id != ?
              AND norm(u.name) LIKE norm(?)
              AND u.profil_sichtbarkeit != 'private'
              AND NOT EXISTS (
                SELECT 1 FROM friendships f
                WHERE (f.requester_id=? AND f.addressee_id=u.id)
                   OR (f.requester_id=u.id AND f.addressee_id=?)
              )
            LIMIT 20
        """, (uid, f"%{q.strip()}%", uid, uid)).fetchall()

    result = []
    for r in rows:
        d = dict(r)
        try:
            d["dogs"] = json.loads(d["dogs_json"]) if d.get("dogs_json") else []
        except Exception:
            d["dogs"] = []
        d.pop("dogs_json", None)
        result.append(d)
    return result


@router.post("/request/{target_id}", status_code=201)
async def send_request(target_id: int, user=Depends(get_current_user)):
    uid = user["id"]
    if uid == target_id:
        raise HTTPException(400, "Du kannst dich nicht selbst als Freund hinzufügen.")

    with db() as conn:
        if not conn.execute("SELECT 1 FROM users WHERE id=?", (target_id,)).fetchone():
            raise HTTPException(404, "Nutzer nicht gefunden.")

        existing = conn.execute("""
            SELECT id, status FROM friendships
            WHERE (requester_id=? AND addressee_id=?) OR (requester_id=? AND addressee_id=?)
        """, (uid, target_id, target_id, uid)).fetchone()

        if existing:
            if existing["status"] == "accepted":
                raise HTTPException(400, "Ihr seid bereits befreundet.")
            raise HTTPException(400, "Anfrage bereits vorhanden.")

        conn.execute(
            "INSERT INTO friendships (requester_id, addressee_id) VALUES (?,?)",
            (uid, target_id)
        )

    # In-App Benachrichtigung + Badge
    try:
        with db() as conn:
            conn.execute(
                """INSERT INTO notifications (user_id, type, title, body, data)
                   VALUES (?, 'friend_request', 'Neue Freundschaftsanfrage', ?, ?)""",
                (target_id,
                 f"{user['name']} möchte dein Freund sein.",
                 '{"page":"friends"}')
            )
    except Exception:
        pass

    try:
        from routes.push import send_push_to_user
        send_push_to_user(target_id, {
            "title": "Neue Freundschaftsanfrage",
            "body":  f"{user['name']} möchte dein Freund sein.",
            "type":  "friend_request",
            "data":  {"page": "friends"},
        })
    except Exception:
        pass

    return {"ok": True}


@router.post("/{friendship_id}/accept")
async def accept_request(friendship_id: int, user=Depends(get_current_user)):
    uid = user["id"]
    with db() as conn:
        f = conn.execute(
            "SELECT * FROM friendships WHERE id=? AND addressee_id=? AND status='pending'",
            (friendship_id, uid)
        ).fetchone()
        if not f:
            raise HTTPException(404, "Anfrage nicht gefunden.")
        conn.execute(
            "UPDATE friendships SET status='accepted', updated_at=datetime('now') WHERE id=?",
            (friendship_id,)
        )
    return {"ok": True}


@router.post("/{friendship_id}/decline")
async def decline_request(friendship_id: int, user=Depends(get_current_user)):
    uid = user["id"]
    with db() as conn:
        f = conn.execute("""
            SELECT id FROM friendships
            WHERE id=? AND (addressee_id=? OR requester_id=?) AND status='pending'
        """, (friendship_id, uid, uid)).fetchone()
        if not f:
            raise HTTPException(404, "Anfrage nicht gefunden.")
        conn.execute("DELETE FROM friendships WHERE id=?", (friendship_id,))
    return {"ok": True}


@router.get("/activity")
async def get_activity(user=Depends(get_current_user)):
    """Aggregierter Aktivitäts-Feed der Freunde (max. 30 Einträge, neueste zuerst)."""
    import json
    uid = user["id"]

    with db() as conn:
        # Alle akzeptierten Freunde ermitteln
        friend_rows = conn.execute("""
            SELECT CASE WHEN requester_id=? THEN addressee_id ELSE requester_id END AS fid
            FROM friendships
            WHERE (requester_id=? OR addressee_id=?) AND status='accepted'
        """, (uid, uid, uid)).fetchall()

        friend_ids = [r["fid"] for r in friend_rows]
        if not friend_ids:
            return []

        ph = ",".join("?" * len(friend_ids))

        # Tagebuch-Einträge der Freunde
        # Gesundheitseinträge der Freunde (nur Typ + Datum, kein Inhalt)
        health_rows = conn.execute(f"""
            SELECT
                'health'         AS type,
                u.id             AS user_id,
                u.name           AS user_name,
                u.avatar_url,
                d.name           AS dog_name,
                d.foto_url       AS dog_foto,
                h.created_at
            FROM health h
            JOIN dogs d  ON d.id  = h.dog_id
            JOIN users u ON u.id  = d.user_id
            WHERE d.user_id IN ({ph})
            ORDER BY h.created_at DESC
            LIMIT 15
        """, friend_ids).fetchall()

        # Gassi-Treffen der Freunde
        walk_rows = conn.execute(f"""
            SELECT
                'walk'           AS type,
                w.id             AS entry_id,
                u.id             AS user_id,
                u.name           AS user_name,
                u.avatar_url,
                NULL             AS dog_name,
                NULL             AS dog_foto,
                w.titel          AS text,
                w.created_at
            FROM walks w
            JOIN users u ON u.id = w.user_id
            WHERE w.user_id IN ({ph})
            ORDER BY w.created_at DESC
            LIMIT 15
        """, friend_ids).fetchall()

        # Forum-Beiträge der Freunde (öffentliche Threads)
        forum_rows = conn.execute(f"""
            SELECT
                'forum'          AS type,
                ft.id            AS entry_id,
                u.id             AS user_id,
                u.name           AS user_name,
                u.avatar_url,
                NULL             AS dog_name,
                NULL             AS dog_foto,
                ft.titel         AS text,
                ft.created_at
            FROM forum_threads ft
            JOIN users u ON u.id = ft.user_id
            WHERE ft.user_id IN ({ph})
            ORDER BY ft.created_at DESC
            LIMIT 15
        """, friend_ids).fetchall()

        # Neue Hunde (angelegt in den letzten 30 Tagen)
        new_dog_rows = conn.execute(f"""
            SELECT
                'new_dog'        AS type,
                u.id             AS user_id,
                u.name           AS user_name,
                u.avatar_url,
                d.name           AS dog_name,
                d.foto_url       AS dog_foto,
                d.created_at
            FROM dogs d
            JOIN users u ON u.id = d.user_id
            WHERE d.user_id IN ({ph})
              AND d.created_at >= datetime('now', '-30 days')
            ORDER BY d.created_at DESC
            LIMIT 15
        """, friend_ids).fetchall()

    _ICON = {
        "diary":   "book-open",
        "health":  "heart",
        "walk":    "paw-print",
        "new_dog": "dog",
        "forum":   "push-pin",
    }
    _TEXT = {
        "health":  "Hat einen Gesundheitseintrag hinzugefügt",
        "new_dog": "Hat einen neuen Hund eingetragen",
    }

    items = []
    for row in [*health_rows, *walk_rows, *forum_rows, *new_dog_rows]:
        d = dict(row)
        t = d["type"]
        items.append({
            "type":       t,
            "entry_id":   d.get("entry_id"),
            "user_id":    d["user_id"],
            "user_name":  d["user_name"],
            "avatar_url": d.get("avatar_url"),
            "dog_name":   d.get("dog_name"),
            "dog_foto":   d.get("dog_foto"),
            "text":       _TEXT.get(t) or (d.get("text") or ""),
            "created_at": d["created_at"],
            "icon":       _ICON[t],
        })

    # Zusammenführen und nach created_at absteigend sortieren, max. 30
    items.sort(key=lambda x: x["created_at"] or "", reverse=True)
    return items[:50]


@router.delete("/{friend_user_id}")
async def remove_friend(friend_user_id: int, user=Depends(get_current_user)):
    uid = user["id"]
    with db() as conn:
        conn.execute("""
            DELETE FROM friendships
            WHERE status='accepted'
              AND ((requester_id=? AND addressee_id=?) OR (requester_id=? AND addressee_id=?))
        """, (uid, friend_user_id, friend_user_id, uid))
    return {"ok": True}
