"""تنظیمات Identity & Access Service."""
from __future__ import annotations

from functools import lru_cache
from typing import Literal

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        case_sensitive=False,
        extra="ignore",
    )

    environment: Literal["development", "staging", "production", "test"] = "development"
    debug: bool = True
    log_level: str = "INFO"
    # نام سرویس با alias اختصاصی تا SERVICE_NAME مشترک (core-service) در .env
    # مقدار این سرویس را بازنویسی نکند.
    service_name: str = Field(
        default="identity-access-service", validation_alias="IDENTITY_SERVICE_NAME"
    )
    api_v1_prefix: str = "/api/v1"

    database_url: str = Field(
        default="postgresql+asyncpg://superapp:superapp_password@localhost:5432/identity_access_db",
        validation_alias="DATABASE_URL",
    )
    database_url_sync: str = Field(
        default="postgresql+psycopg://superapp:superapp_password@localhost:5432/identity_access_db",
        validation_alias="DATABASE_URL_SYNC",
    )

    # Core Platform (برای اعتبارسنجی tenant هنگام عضویت)
    core_service_url: str = Field(default="http://localhost:8000", validation_alias="CORE_SERVICE_URL")

    # Keycloak / SSO
    keycloak_enabled: bool = True
    # آدرس داخلی (Docker network) برای Admin API و token exchange
    keycloak_server_url: str = "http://localhost:8080"
    # آدرس عمومی برای redirect مرورگر (معمولاً localhost:8080 در dev)
    keycloak_public_url: str = Field(
        default="", validation_alias="KEYCLOAK_PUBLIC_URL"
    )
    keycloak_realm: str = "superapp"
    keycloak_admin_user: str = "admin"
    keycloak_admin_password: str = "admin"
    keycloak_client_id: str = Field(
        default="identity-access-service",
        validation_alias="IDENTITY_KEYCLOAK_CLIENT_ID",
    )
    keycloak_client_secret: str = Field(
        default="change-me-identity",
        validation_alias="KEYCLOAK_IDENTITY_CLIENT_SECRET",
    )
    keycloak_frontend_client_id: str = Field(
        default="superapp-frontend", validation_alias="KEYCLOAK_FRONTEND_CLIENT_ID"
    )

    jwt_algorithm: str = "RS256"
    jwt_audience: str = "account"
    jwt_verify_signature: bool = True
    auth_required: bool = True

    # آدرس callback فرانت‌اند پس از لاگین Keycloak
    frontend_callback_url: str = Field(
        default="http://localhost:3000/auth/callback", validation_alias="FRONTEND_CALLBACK_URL"
    )
    platform_admin_mobiles: str = Field(
        default="", validation_alias="PLATFORM_ADMIN_MOBILES"
    )
    cors_origins: str = Field(
        default="http://torbatyar.xyz:3000,http://localhost:3000,http://127.0.0.1:3000",
        validation_alias="CORS_ORIGINS",
    )

    @property
    def platform_admin_mobile_set(self) -> set[str]:
        from shared.phone import normalize_mobile

        result: set[str] = set()
        for raw in self.platform_admin_mobiles.split(","):
            raw = raw.strip()
            if not raw:
                continue
            try:
                result.add(normalize_mobile(raw))
            except ValueError:
                continue
        return result

    @property
    def cors_origin_list(self) -> list[str]:
        origins = [origin.strip() for origin in self.cors_origins.split(",") if origin.strip()]
        kc = self.keycloak_public_url.rstrip("/") if self.keycloak_public_url else ""
        if kc and kc not in origins:
            origins.append(kc)
        return origins

    @property
    def keycloak_admin_url(self) -> str:
        return f"{self.keycloak_server_url}/admin/realms/{self.keycloak_realm}"

    @property
    def keycloak_browser_url(self) -> str:
        return self.keycloak_public_url or self.keycloak_server_url

    @property
    def keycloak_realm_url(self) -> str:
        return f"{self.keycloak_server_url}/realms/{self.keycloak_realm}"

    @property
    def keycloak_public_realm_url(self) -> str:
        return f"{self.keycloak_browser_url}/realms/{self.keycloak_realm}"

    @property
    def oidc_auth_url(self) -> str:
        return f"{self.keycloak_realm_url}/protocol/openid-connect/auth"

    @property
    def oidc_public_auth_url(self) -> str:
        return f"{self.keycloak_public_realm_url}/protocol/openid-connect/auth"

    @property
    def oidc_token_url(self) -> str:
        return f"{self.keycloak_realm_url}/protocol/openid-connect/token"

    @property
    def oidc_public_token_url(self) -> str:
        return f"{self.keycloak_public_realm_url}/protocol/openid-connect/token"

    @property
    def oidc_public_logout_url(self) -> str:
        return f"{self.keycloak_public_realm_url}/protocol/openid-connect/logout"

    @property
    def oidc_logout_url(self) -> str:
        return f"{self.keycloak_realm_url}/protocol/openid-connect/logout"

    @property
    def oidc_public_userinfo_url(self) -> str:
        return f"{self.keycloak_public_realm_url}/protocol/openid-connect/userinfo"

    @property
    def oidc_userinfo_url(self) -> str:
        return f"{self.keycloak_realm_url}/protocol/openid-connect/userinfo"


@lru_cache
def get_settings() -> Settings:
    return Settings()


settings = get_settings()
