"""Конфигурация сервиса: настройки и список порталов из .env."""
from __future__ import annotations

import os
from dataclasses import dataclass

from dotenv import load_dotenv

load_dotenv()


@dataclass(frozen=True)
class PortalConfig:
    domain: str          # например acme.bitrix24.ru
    client_id: str
    client_secret: str

    @property
    def key(self) -> str:
        """Префикс переменных окружения для домена."""
        return self.domain.upper().replace(".", "_").replace("-", "_")

    @property
    def rest_base(self) -> str:
        return f"https://{self.domain}/rest"

    @property
    def authorize_url(self) -> str:
        return f"https://{self.domain}/oauth/authorize/"


@dataclass(frozen=True)
class Settings:
    anthropic_api_key: str
    draft_model: str
    draft_max_tokens: int
    public_base_url: str
    poll_interval: int
    context_limit: int
    portals: dict[str, PortalConfig]

    @property
    def oauth_token_url(self) -> str:
        # Единый сервер авторизации приложений Битрикс.
        return "https://oauth.bitrix.info/oauth/token/"

    @property
    def redirect_uri(self) -> str:
        return f"{self.public_base_url.rstrip('/')}/oauth/callback"

    @property
    def event_handler_url(self) -> str:
        return f"{self.public_base_url.rstrip('/')}/bot/events"


def load_settings() -> Settings:
    """Собирает конфиг и проверяет ВСЕ обязательные переменные сразу,
    выдавая единый список недостающих с точными именами."""
    missing: list[str] = []

    def need(name: str) -> str:
        val = os.getenv(name, "").strip()
        if not val:
            missing.append(name)
        return val

    api_key = need("ANTHROPIC_API_KEY")
    public_base = need("PUBLIC_BASE_URL")

    raw_portals = os.getenv("BITRIX_PORTALS", "").strip()
    if not raw_portals:
        missing.append("BITRIX_PORTALS")
    domains = [d.strip() for d in raw_portals.split(",") if d.strip()]

    portals: dict[str, PortalConfig] = {}
    for domain in domains:
        key = domain.upper().replace(".", "_").replace("-", "_")
        cid = need(f"{key}_CLIENT_ID")
        csec = need(f"{key}_CLIENT_SECRET")
        portals[domain] = PortalConfig(domain=domain, client_id=cid, client_secret=csec)

    if missing:
        hint = ""
        if domains:
            expected = "\n".join(
                f"    {d.upper().replace('.', '_').replace('-', '_')}_CLIENT_ID / _CLIENT_SECRET"
                for d in domains
            )
            hint = (
                "\n\nДля порталов из BITRIX_PORTALS ожидаются переменные "
                f"(имя = домен в ВЕРХНЕМ регистре, точки/дефисы -> '_'):\n{expected}"
            )
        raise RuntimeError(
            "Не заданы обязательные переменные окружения:\n  - "
            + "\n  - ".join(missing)
            + hint
            + "\n\nЗаполни их в .env (см. .env.example)."
        )

    return Settings(
        anthropic_api_key=api_key,
        draft_model=os.getenv("DRAFT_MODEL", "claude-sonnet-4-6"),
        draft_max_tokens=int(os.getenv("DRAFT_MAX_TOKENS", "600")),
        public_base_url=public_base,
        poll_interval=int(os.getenv("POLL_INTERVAL_SECONDS", "20")),
        context_limit=int(os.getenv("CONTEXT_MESSAGE_LIMIT", "12")),
        portals=portals,
    )


settings = load_settings()
