from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Any


def _mask_value(value: str) -> str:
    text = str(value or "")
    if not text:
        return ""
    if len(text) <= 8:
        return "*" * len(text)
    return text[:4] + "*" * (len(text) - 8) + text[-4:]


def _mask_header_value(key: str, value: str) -> str:
    if key.lower() == "authorization":
        scheme, _, token = str(value).partition(" ")
        if scheme and token:
            return f"{scheme} {_mask_value(token)}"
    return _mask_value(str(value))


class AuthSurface(str, Enum):
    BRIDGE = "bridge"
    RUNTIME = "runtime"


class AuthAttemptOutcome(str, Enum):
    SELECTED = "selected"
    MISSING = "missing"
    REJECTED = "rejected"
    SHADOWED = "shadowed"
    SKIPPED = "skipped"


class AuthSource(str, Enum):
    EXPLICIT = "explicit"
    ENV = "env"
    CONFIG = "config"
    LICENSE_JWT = "license_jwt"
    PROVIDER = "provider"
    SERVER_SESSION = "server_session"
    LEGACY_FILE = "legacy_file"
    DEV_MODE = "dev_mode"
    NONE = "none"


class RefreshStrategy(str, Enum):
    NONE = "none"
    LOCAL_REFRESH = "local_refresh"
    SERVER_REFRESH = "server_refresh"


@dataclass
class AuthAttempt:
    source: AuthSource
    outcome: AuthAttemptOutcome
    detail: str
    field: str = "auth"
    value_hint: str | None = None
    workspace_id: str | None = None
    api_base: str | None = None

    def to_safe_dict(self) -> dict[str, Any]:
        return {
            "source": self.source.value,
            "outcome": self.outcome.value,
            "detail": self.detail,
            "field": self.field,
            "value_hint": _mask_value(self.value_hint or "") if self.value_hint else None,
            "workspace_id": self.workspace_id,
            "api_base": self.api_base,
        }


@dataclass
class AuthResolution:
    surface: AuthSurface
    integration: str
    selected_source: AuthSource = AuthSource.NONE
    attempts: list[AuthAttempt] = field(default_factory=list)
    headers: dict[str, str] = field(default_factory=dict)
    credentials: dict[str, str] = field(default_factory=dict)
    workspace_id: str | None = None
    api_base: str | None = None
    mode: str | None = None
    refresh_strategy: RefreshStrategy = RefreshStrategy.NONE
    warnings: list[str] = field(default_factory=list)

    @property
    def has_auth(self) -> bool:
        return bool(self.headers or self.credentials)

    def to_safe_dict(self) -> dict[str, Any]:
        return {
            "surface": self.surface.value,
            "integration": self.integration,
            "selected_source": self.selected_source.value,
            "attempts": [attempt.to_safe_dict() for attempt in self.attempts],
            "headers": {
                key: _mask_header_value(key, value)
                for key, value in self.headers.items()
            },
            "credentials": {
                key: _mask_value(str(value))
                for key, value in self.credentials.items()
                if value not in (None, "")
            },
            "workspace_id": self.workspace_id,
            "api_base": self.api_base,
            "mode": self.mode,
            "refresh_strategy": self.refresh_strategy.value,
            "warnings": list(self.warnings),
        }
