"""
Activity: Create organization in Logto.
"""

import logging
from functools import lru_cache
from time import time

import httpx
from temporalio import activity

from optovia_workflows.types import CreateLogtoOrgInput, CreateLogtoOrgResult

from ..config import settings

logger = logging.getLogger(__name__)

# Token cache
_token_cache: dict = {"token": None, "expires_at": 0}


def _get_m2m_token() -> str:
    """
    Get M2M access token from Logto.
    Tokens are cached until expiry.
    """
    now = time()

    # Return cached token if still valid (with 60s buffer)
    if _token_cache["token"] and _token_cache["expires_at"] > now + 60:
        return _token_cache["token"]

    logger.info("Fetching new Logto M2M token")

    with httpx.Client(timeout=settings.LOGTO_TIMEOUT) as client:
        response = client.post(
            f"http://{settings.LOGTO_INTERNAL_URL}/oidc/token",
            data={
                "grant_type": "client_credentials",
                "client_id": settings.LOGTO_M2M_APP_ID,
                "client_secret": settings.LOGTO_M2M_APP_SECRET,
                "resource": settings.LOGTO_M2M_RESOURCE,
                "scope": "all",
            },
            headers={"Content-Type": "application/x-www-form-urlencoded"},
        )
        response.raise_for_status()
        result = response.json()

    _token_cache["token"] = result["access_token"]
    _token_cache["expires_at"] = now + result.get("expires_in", 3600)

    logger.info("Logto M2M token obtained, expires in %ds", result.get("expires_in", 3600))
    return _token_cache["token"]


@activity.defn(name="create_logto_org")
def create_logto_org(data: CreateLogtoOrgInput) -> CreateLogtoOrgResult:
    """
    Create organization in Logto.

    This is a synchronous activity (runs in ThreadPoolExecutor).
    """
    url = f"http://{settings.LOGTO_INTERNAL_URL}/api/organizations"

    logger.info(
        "Creating Logto organization for team %s (%s)",
        data.team_id,
        data.team_name,
    )

    # Get M2M token for authentication
    token = _get_m2m_token()

    with httpx.Client(timeout=settings.LOGTO_TIMEOUT) as client:
        response = client.post(
            url,
            json={
                "name": data.team_name,
                "description": f"Organization for team {data.team_id}",
                "metadata": {"team_id": data.team_id, "owner_id": data.owner_id},
            },
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {token}",
            },
        )
        response.raise_for_status()
        result = response.json()

    org_id = result.get("id", "")
    logger.info(
        "Logto organization created: org_id=%s for team=%s",
        org_id,
        data.team_id,
    )

    return CreateLogtoOrgResult(
        team_id=data.team_id,
        organization_id=org_id,
        created=True,
    )
