"""Public visitor-tracking endpoints.

Mounted at ``/api/v1/track``. These are intentionally unauthenticated so the
frontend `useVisitorTracking` hook can post pageviews/events without holding
a JWT. Ingest is best-effort: malformed payloads get a 200 OK with
``ok=false`` rather than leaking error details.
"""

from __future__ import annotations

import logging
from typing import Optional

from core.database import get_db
from fastapi import APIRouter, Depends, Request
from schemas.auth import UserResponse
from schemas.visitor_monitor import TrackAck, TrackEventIn, TrackPageviewIn
from services.visitor_monitor import record_event, record_pageview
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/track", tags=["visitor-tracking"])


async def _optional_user(request: Request) -> Optional[UserResponse]:
    """Extract an authenticated user from the Authorization header if present.

    We never fail the request if no/invalid token is present; tracking should
    work for anonymous visitors too.
    """
    auth = request.headers.get("authorization") or ""
    if not auth.lower().startswith("bearer "):
        return None
    token = auth.split(" ", 1)[1].strip()
    if not token:
        return None
    try:
        from core.auth import decode_access_token  # lazy
        payload = decode_access_token(token)
    except Exception:  # noqa: BLE001
        return None
    user_id = payload.get("sub")
    if not user_id:
        return None
    return UserResponse(
        id=user_id,
        email=payload.get("email", ""),
        name=payload.get("name"),
        role=payload.get("role", "user"),
        last_login=None,
    )


@router.post("/pageview", response_model=TrackAck)
async def track_pageview(
    payload: TrackPageviewIn,
    request: Request,
    db: AsyncSession = Depends(get_db),
) -> TrackAck:
    user = await _optional_user(request)
    try:
        _ok, excluded = await record_pageview(
            db,
            request=request,
            session_id=payload.session_id,
            page=payload.page,
            referrer=payload.referrer,
            utm={
                "utm_source": payload.utm_source,
                "utm_medium": payload.utm_medium,
                "utm_campaign": payload.utm_campaign,
                "utm_term": payload.utm_term,
                "utm_content": payload.utm_content,
            },
            user_id=user.id if user else None,
            user_role=user.role if user else None,
        )
        return TrackAck(ok=True, excluded=excluded)
    except Exception:  # noqa: BLE001
        logger.exception("[track] pageview failed")
        return TrackAck(ok=False, excluded=False)


@router.post("/event", response_model=TrackAck)
async def track_event(
    payload: TrackEventIn,
    request: Request,
    db: AsyncSession = Depends(get_db),
) -> TrackAck:
    user = await _optional_user(request)
    try:
        _ok, excluded = await record_event(
            db,
            request=request,
            session_id=payload.session_id,
            event_type=payload.event_type,
            label=payload.label,
            page=payload.page,
            metadata=payload.metadata,
            user_id=user.id if user else None,
            user_role=user.role if user else None,
        )
        return TrackAck(ok=True, excluded=excluded)
    except Exception:  # noqa: BLE001
        logger.exception("[track] event failed")
        return TrackAck(ok=False, excluded=False)


@router.post("/heartbeat", response_model=TrackAck)
async def track_heartbeat(
    payload: TrackEventIn,
    request: Request,
    db: AsyncSession = Depends(get_db),
) -> TrackAck:
    """Lightweight liveness ping; reuses the event table with ``event_type='heartbeat'``."""
    user = await _optional_user(request)
    try:
        _ok, excluded = await record_event(
            db,
            request=request,
            session_id=payload.session_id,
            event_type="heartbeat",
            label=None,
            page=payload.page,
            metadata=None,
            user_id=user.id if user else None,
            user_role=user.role if user else None,
        )
        return TrackAck(ok=True, excluded=excluded)
    except Exception:  # noqa: BLE001
        logger.exception("[track] heartbeat failed")
        return TrackAck(ok=False, excluded=False)