import logging
from datetime import datetime, timedelta, timezone
from typing import Any, Optional
from urllib.parse import urlparse

from sqlalchemy.orm import Session

from api.v1.modules.core.user_tenant.models import UserTenant
from core.workspace_profile_client import WorkspaceProfileClient

logger = logging.getLogger(__name__)

SYNC_TTL_SECONDS = 300


def _is_valid_http_url(url: Optional[str]) -> bool:
    if not url or not isinstance(url, str):
        return False
    parsed = urlparse(url.strip())
    return parsed.scheme in ("http", "https") and bool(parsed.netloc)


def _is_fresh(ts: Optional[datetime], ttl_seconds: int = SYNC_TTL_SECONDS) -> bool:
    if not ts:
        return False
    now = datetime.now(timezone.utc)
    if ts.tzinfo is None:
        ts = ts.replace(tzinfo=timezone.utc)
    return ts >= (now - timedelta(seconds=ttl_seconds))


async def sync_workspace_profile_for_user(
    db: Session,
    *,
    access_token: Optional[str],
    keycloak_user_id: Optional[str],
    tenant_id: Optional[int] = None,
    company_id: Optional[int] = None,
    workspace_profile: Optional[dict[str, Any]] = None,
    force: bool = False,
) -> None:
    """
    Sincroniza sub/avatar_url desde Workspace hacia core.user_tenants.
    Nunca lanza excepción para no bloquear login ni requests autenticados.
    """
    if not access_token or not keycloak_user_id:
        return

    try:
        query = db.query(UserTenant).filter(
            UserTenant.keycloak_user_id == keycloak_user_id,
            UserTenant.is_active == True,
        )
        if tenant_id is not None:
            query = query.filter(UserTenant.tenant_id == int(tenant_id))
        if company_id is not None:
            query = query.filter(UserTenant.company_id == int(company_id))

        target = query.first()
        if not target:
            return

        if not force and _is_fresh(target.workspace_profile_synced_at):
            return

        payload = workspace_profile
        if payload is None:
            client = WorkspaceProfileClient()
            payload = await client.get_me(access_token)

        workspace_sub = payload.get("sub")
        if not workspace_sub:
            logger.warning(
                "workspace_profile_sync_warning",
                extra={
                    "event": "workspace_profile_sync_warning",
                    "reason": "missing_sub",
                    "keycloak_user_id": keycloak_user_id,
                    "tenant_id": target.tenant_id,
                },
            )
            return

        avatar_url = payload.get("avatar_url")
        sanitized_avatar = avatar_url.strip() if isinstance(avatar_url, str) else None
        if sanitized_avatar and not _is_valid_http_url(sanitized_avatar):
            logger.warning(
                "workspace_profile_sync_warning",
                extra={
                    "event": "workspace_profile_sync_warning",
                    "reason": "invalid_avatar_url",
                    "keycloak_user_id": keycloak_user_id,
                    "tenant_id": target.tenant_id,
                },
            )
            sanitized_avatar = None

        target.workspace_user_id = str(workspace_sub)
        target.workspace_avatar_url = sanitized_avatar
        target.workspace_profile_synced_at = datetime.now(timezone.utc)
        db.add(target)
        db.commit()
    except Exception as exc:
        db.rollback()
        logger.warning(
            "workspace_profile_sync_failed",
            extra={
                "event": "workspace_profile_sync_failed",
                "error": str(exc),
                "keycloak_user_id": keycloak_user_id,
                "tenant_id": tenant_id,
                "company_id": company_id,
            },
        )
