from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict


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

    # App
    APP_NAME: str = "Notification Service"
    APP_ENV: str = "dev"
    SECRET_KEY: str = "changeme"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24
    APP_DOMAIN: str = "localhost:8000"  # Домен приложения для webhook URL
    
    # Encryption
    ENCRYPTION_KEY: str = "changeme_encryption_key_32_chars"  # 32 chars for AES-256

    # DB
    POSTGRES_HOST: str = "postgres"
    POSTGRES_PORT: int = 5432
    POSTGRES_DB: str = "notifications"
    POSTGRES_USER: str = "postgres"
    POSTGRES_PASSWORD: str = "postgres"
    POSTGRES_SCHEMA: str = "public"

    # Redis / Celery
    REDIS_URL: str = "redis://redis:6379/0"
    CELERY_BROKER_URL: str | None = None
    CELERY_RESULT_BACKEND: str | None = None

    # Email
    SMTP_HOST: str = "mailhog"
    SMTP_PORT: int = 1025
    SMTP_USER: str | None = None
    SMTP_PASSWORD: str | None = None
    EMAIL_FROM: str = "no-reply@example.com"
    EMAIL_REPLY_TO: str | None = None

    # Telegram - System Bot
    SYSTEM_TG_BOT_TOKEN: str | None = None
    SYSTEM_TG_BOT_USERNAME: str = "@QuickNotifyServiceBot"
    TG_WEBHOOK_BASE: str = "https://localhost:3000/tg"
    
    # Legacy Telegram (for backward compatibility)
    TELEGRAM_BOT_TOKEN: str | None = None

    # Test Telegram client for admin testing
    TEST_TELEGRAM_CHAT_ID: str | None = None
    
    # Telegram Client API (MTProto) - для отправки без /start
    TELEGRAM_API_ID: int | None = None  # Получить на https://my.telegram.org
    TELEGRAM_API_HASH: str | None = None  # Получить на https://my.telegram.org
    TELEGRAM_PHONE: str | None = None  # Номер телефона в формате +79991234567
    TELEGRAM_SESSION_PATH: str = "telegram_session"  # Путь для сохранения сессии

    # VK
    VK_GROUP_TOKEN: str | None = None

    # Bitrix24 Marketplace App credentials
    BITRIX_CLIENT_ID: str | None = None
    BITRIX_CLIENT_SECRET: str | None = None
    BITRIX_REDIRECT_URI: str = "http://localhost:3000/api/integrations/bitrix/oauth/callback"

    # Rate limiting
    RATE_LIMIT_BUCKET_SIZE: int = 60
    RATE_LIMIT_REFILL_RATE_PER_SEC: float = 1.0
    
    # Scheduled notifications batching
    SCHEDULED_NOTIFICATIONS_BATCH_SIZE: int = 100  # Максимум уведомлений для обработки за один запуск
    
    # Notification creation limits
    NOTIFICATION_CREATION_RATE_LIMIT_BUCKET_SIZE: int = 30  # Количество созданий уведомлений за период
    NOTIFICATION_CREATION_RATE_LIMIT_REFILL_RATE_PER_SEC: float = 1.0  # Скорость пополнения токенов
    MAX_RECIPIENTS_PER_NOTIFICATION: int = 10000  # Максимум получателей в одном уведомлении (сегмент)
    MAX_NOTIFICATIONS_PER_TENANT_PER_MINUTE: int = 60  # Максимум уведомлений от одного тенанта в минуту

    @property
    def database_url(self) -> str:
        return (
            f"postgresql+psycopg2://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}"
            f"@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB}"
        )

    @property
    def celery_broker_url(self) -> str:
        return self.CELERY_BROKER_URL or self.REDIS_URL

    @property
    def celery_result_backend(self) -> str:
        return self.CELERY_RESULT_BACKEND or self.REDIS_URL


@lru_cache
def get_settings() -> Settings:
    return Settings()  # type: ignore[call-arg]

