"""
Profile Management Endpoints for Mitai Jinkendo

Handles profile CRUD operations for both admin and current user.
"""
import uuid
from typing import Optional
from datetime import datetime

from fastapi import APIRouter, HTTPException, Header, Depends

from db import get_db, get_cursor, r2d
from auth import require_auth
from models import ProfileCreate, ProfileUpdate

router = APIRouter(prefix="/api", tags=["profiles"])


# ── Helper ────────────────────────────────────────────────────────────────────
def get_pid(x_profile_id: Optional[str] = Header(default=None)) -> str:
    """Get profile_id - from header for legacy endpoints."""
    if x_profile_id:
        return x_profile_id
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT id FROM profiles ORDER BY created LIMIT 1")
        row = cur.fetchone()
        if row: return row['id']
    raise HTTPException(400, "Kein Profil gefunden")


# ── Admin Profile Management ──────────────────────────────────────────────────
@router.get("/profiles")
def list_profiles(session=Depends(require_auth)):
    """List all profiles (admin)."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT * FROM profiles ORDER BY created")
        rows = cur.fetchall()
        return [r2d(r) for r in rows]


@router.post("/profiles")
def create_profile(p: ProfileCreate, session=Depends(require_auth)):
    """Create new profile (admin)."""
    pid = str(uuid.uuid4())
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("""INSERT INTO profiles (id,name,avatar_color,sex,dob,height,goal_weight,goal_bf_pct,created,updated)
            VALUES (%s,%s,%s,%s,%s,%s,%s,%s,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)""",
            (pid,p.name,p.avatar_color,p.sex,p.dob,p.height,p.goal_weight,p.goal_bf_pct))
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT * FROM profiles WHERE id=%s", (pid,))
        return r2d(cur.fetchone())


@router.get("/profiles/{pid}")
def get_profile(pid: str, session=Depends(require_auth)):
    """Get profile by ID."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT * FROM profiles WHERE id=%s", (pid,))
        row = cur.fetchone()
        if not row: raise HTTPException(404, "Profil nicht gefunden")
        return r2d(row)


@router.put("/profiles/{pid}")
def update_profile(pid: str, p: ProfileUpdate, session=Depends(require_auth)):
    """Update profile by ID."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT * FROM profiles WHERE id=%s", (pid,))
        row = cur.fetchone()
        if not row:
            raise HTTPException(404, "Profil nicht gefunden")
        rowd = r2d(row)
        cur_email_norm = (rowd.get("email") or "").strip().lower()

        patch = p.model_dump(exclude_unset=True)
        data = {}

        if "email" in patch:
            ev = patch["email"]
            if ev is None or (isinstance(ev, str) and ev.strip() == ""):
                if rowd.get("email") is not None:
                    data["email"] = None
                    data["email_verified"] = False
                    data["verification_token"] = None
                    data["verification_expires"] = None
            else:
                email_norm = ev.strip().lower()
                if "@" not in email_norm or len(email_norm) < 5:
                    raise HTTPException(400, "Ungültige E-Mail-Adresse")
                cur.execute(
                    """
                    SELECT id FROM profiles
                    WHERE email IS NOT NULL AND lower(trim(email)) = %s AND id <> %s
                    """,
                    (email_norm, pid),
                )
                if cur.fetchone():
                    raise HTTPException(409, "E-Mail wird bereits verwendet")
                data["email"] = email_norm
                if email_norm != cur_email_norm:
                    data["email_verified"] = False
                    data["verification_token"] = None
                    data["verification_expires"] = None

        nullable_keys = {"goal_weight", "goal_bf_pct", "dob"}
        for k, v in patch.items():
            if k == "email":
                continue
            if v is None and k in nullable_keys:
                data[k] = None
            elif v is not None:
                data[k] = v

        if not data:
            return get_profile(pid, session)

        data["updated"] = datetime.now().isoformat()
        cols = ", ".join(f"{k}=%s" for k in data)
        vals = list(data.values()) + [pid]
        cur.execute(f"UPDATE profiles SET {cols} WHERE id=%s", vals)
    return get_profile(pid, session)


@router.delete("/profiles/{pid}")
def delete_profile(pid: str, session=Depends(require_auth)):
    """Delete profile (admin)."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("SELECT COUNT(*) as count FROM profiles")
        count = cur.fetchone()['count']
        if count <= 1: raise HTTPException(400, "Letztes Profil kann nicht gelöscht werden")
        for table in ['weight_log','circumference_log','caliper_log','nutrition_log','activity_log','ai_insights']:
            cur.execute(f"DELETE FROM {table} WHERE profile_id=%s", (pid,))
        cur.execute("DELETE FROM profiles WHERE id=%s", (pid,))
    return {"ok": True}


# ── Current User Profile ──────────────────────────────────────────────────────
@router.get("/profile")
def get_active_profile(x_profile_id: Optional[str] = Header(default=None), session: dict = Depends(require_auth)):
    """Legacy endpoint – returns active profile."""
    pid = get_pid(x_profile_id)
    return get_profile(pid, session)


@router.put("/profile")
def update_active_profile(p: ProfileUpdate, x_profile_id: Optional[str] = Header(default=None), session: dict = Depends(require_auth)):
    """Update current user's profile."""
    pid = get_pid(x_profile_id)
    return update_profile(pid, p, session)
