"""
Telemetry service (4A).

Single entry-point for writing canonical product events.
"""

from __future__ import annotations

import hashlib
import json
from typing import Any, Optional

from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession

from app.config import get_settings
from app.models.telemetry import TelemetryEvent


settings = get_settings()


def _hash_ip(ip: str) -> str:
    return hashlib.sha256(f"{ip}|{settings.secret_key}".encode()).hexdigest()[:32]


def _get_client_ip(request: Request) -> Optional[str]:
    xff = request.headers.get("x-forwarded-for")
    if xff:
        ip = xff.split(",")[0].strip()
        if ip:
            return ip
    cf_ip = request.headers.get("cf-connecting-ip")
    if cf_ip:
        return cf_ip.strip()
    return request.client.host if request.client else None


async def track_event(
    db: AsyncSession,
    *,
    event_name: str,
    request: Optional[Request] = None,
    user_id: Optional[int] = None,
    is_authenticated: Optional[bool] = None,
    source: Optional[str] = None,
    domain: Optional[str] = None,
    listing_id: Optional[int] = None,
    inquiry_id: Optional[int] = None,
    yield_domain_id: Optional[int] = None,
    click_id: Optional[str] = None,
    referrer: Optional[str] = None,
    user_agent: Optional[str] = None,
    metadata: Optional[dict[str, Any]] = None,
) -> None:
    ip_hash = None
    if request is not None:
        ip = _get_client_ip(request)
        ip_hash = _hash_ip(ip) if ip else None
        user_agent = user_agent or request.headers.get("user-agent")
        referrer = referrer or request.headers.get("referer")

    row = TelemetryEvent(
        user_id=user_id,
        event_name=event_name,
        listing_id=listing_id,
        inquiry_id=inquiry_id,
        yield_domain_id=yield_domain_id,
        click_id=click_id[:64] if click_id else None,
        domain=domain,
        source=source,
        ip_hash=ip_hash,
        user_agent=user_agent[:500] if user_agent else None,
        referrer=referrer[:500] if referrer else None,
        metadata_json=json.dumps(metadata or {}, ensure_ascii=False) if metadata else None,
        is_authenticated=is_authenticated,
    )
    db.add(row)

