import uuid as uuid_module

import structlog

from control_plane_api.app.middleware.request_id import get_request_id
from control_plane_api.app.observability.optional import get_current_span

logger = structlog.get_logger()


def log_if_invalid_user_id(value, *, source: str, **extra_context) -> bool:
    """Check if value is a valid UUID. Logs a warning if not. Returns True if valid."""
    span = get_current_span()
    request_id = get_request_id()

    if span and span.is_recording():
        if request_id:
            span.set_attribute("request_id", request_id)

    if value is None:
        if span and span.is_recording():
            span.set_attribute("user_id.valid", True)
            span.set_attribute("user_id.present", False)
            span.set_attribute("user_id.validation_source", source)
        return True
    try:
        uuid_module.UUID(str(value))
        if span and span.is_recording():
            span.set_attribute("user_id.valid", True)
            span.set_attribute("user_id.present", True)
            span.set_attribute("user_id.validation_source", source)
        return True
    except (ValueError, TypeError, AttributeError):
        if span and span.is_recording():
            span.set_attribute("user_id.valid", False)
            span.set_attribute("user_id.present", True)
            span.set_attribute("user_id.raw_value", str(value))
            span.set_attribute("user_id.validation_source", source)
            event_attrs = {"source": source, "raw_value": str(value)}
            for k, v in extra_context.items():
                event_attrs[k] = str(v)
            span.add_event("invalid_user_id_detected", event_attrs)

        logger.warning(
            "invalid_user_id_detected",
            raw_value=value,
            value_type=type(value).__name__,
            value_length=len(str(value)),
            source=source,
            **extra_context,
        )
        return False
