from __future__ import annotations

import hashlib
import json
import logging
import time
from typing import Any, Dict, Optional


def build_trace_id(*parts: str) -> str:
    raw = "|".join(str(p or "") for p in parts)
    digest = hashlib.md5(raw.encode("utf-8")).hexdigest()
    return digest[:16]


def emit_activity(
    logger: logging.Logger,
    *,
    event: str,
    trace_id: str = "",
    customer_id: str = "",
    result: str = "ok",
    latency_ms: Optional[int] = None,
    **fields: Any,
) -> None:
    payload: Dict[str, Any] = {
        "trace_id": trace_id or "-",
        "customer_id": customer_id or "-",
        "event": event,
        "result": result,
    }
    if latency_ms is not None:
        payload["latency_ms"] = int(max(0, latency_ms))
    for k, v in (fields or {}).items():
        if isinstance(v, str):
            payload[k] = v[:400]
        else:
            payload[k] = v
    try:
        logger.info(f"[ACTIVITY] {json.dumps(payload, ensure_ascii=False)}")
    except Exception:
        logger.info(f"[ACTIVITY] {payload}")


class ActivityTimer:
    def __init__(
        self,
        *,
        logger: logging.Logger,
        event: str,
        trace_id: str = "",
        customer_id: str = "",
        **fields: Any,
    ):
        self.logger = logger
        self.event = event
        self.trace_id = trace_id
        self.customer_id = customer_id
        self.fields = fields
        self.start = time.monotonic()

    def ok(self, **fields: Any) -> None:
        elapsed_ms = int((time.monotonic() - self.start) * 1000)
        merged = dict(self.fields)
        merged.update(fields)
        emit_activity(
            self.logger,
            event=self.event,
            trace_id=self.trace_id,
            customer_id=self.customer_id,
            result="ok",
            latency_ms=elapsed_ms,
            **merged,
        )

    def fail(self, error: str, **fields: Any) -> None:
        elapsed_ms = int((time.monotonic() - self.start) * 1000)
        merged = dict(self.fields)
        merged.update(fields)
        emit_activity(
            self.logger,
            event=self.event,
            trace_id=self.trace_id,
            customer_id=self.customer_id,
            result="error",
            latency_ms=elapsed_ms,
            error=error,
            **merged,
        )
