from __future__ import annotations

from datetime import UTC
from datetime import datetime
from datetime import timedelta

import jwt
import pytest

from amsdal_ml.mcp_server.mcp_oauth.services.types import JWT_ALGORITHM
from amsdal_ml.mcp_server.mcp_oauth.services.types import ClientIdTokenClaims
from amsdal_ml.mcp_server.mcp_oauth.services.types import OAuthConstants
from amsdal_ml.ml_config import ml_config


@pytest.fixture(autouse=True)
def oauth_defaults(monkeypatch):
    monkeypatch.setattr(ml_config, 'oauth_enabled', True)
    monkeypatch.setattr(ml_config, 'oauth_issuer', 'http://127.0.0.1:8000')
    monkeypatch.setattr(ml_config, 'oauth_code_exp_minutes', 10)
    monkeypatch.setattr(ml_config, 'oauth_access_token_exp_hours', 24)
    monkeypatch.setattr(ml_config, 'oauth_refresh_token_exp_days', 90)


@pytest.fixture
def oauth_signing_key(monkeypatch) -> str:
    from amsdal.contrib.auth.settings import auth_settings

    key = 'test-oauth-signing-key'
    monkeypatch.setattr(auth_settings, 'AUTH_JWT_KEY', key, raising=False)
    return key


@pytest.fixture
def build_client_id():
    def _build_client_id(
        signing_key: str,
        *,
        redirect_uris: list[str] | None = None,
        issuer: str | None = None,
    ) -> str:
        now = datetime.now(tz=UTC)
        payload = {
            ClientIdTokenClaims.ISSUED_AT.value: int(now.timestamp()),
            ClientIdTokenClaims.EXPIRATION.value: int((now + timedelta(hours=1)).timestamp()),
            ClientIdTokenClaims.JWT_ID.value: 'client-jti',
            ClientIdTokenClaims.ISSUER.value: issuer or ml_config.oauth_issuer,
            ClientIdTokenClaims.REDIRECT_URIS.value: redirect_uris or [],
            ClientIdTokenClaims.GRANT_TYPES.value: ['authorization_code'],
            ClientIdTokenClaims.RESPONSE_TYPES.value: ['code'],
            ClientIdTokenClaims.TOKEN_ENDPOINT_AUTH_METHOD.value: OAuthConstants.TOKEN_ENDPOINT_AUTH_NONE.value,
        }
        return jwt.encode(payload, signing_key, algorithm=JWT_ALGORITHM)

    return _build_client_id
