from pathlib import Path
from urllib.parse import urlparse, ParseResult
from typing import Optional, Any
from secrets import token_urlsafe

from pydantic import field_validator, model_validator, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from aiogram.types import ChatAdministratorRights


class _Settings(BaseSettings):
    """Настройки бота с комплексной валидацией"""
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
        case_sensitive=False,
        validate_default=True,
    )

    # ============== ОСНОВНЫЕ ПАРАМЕТРЫ ==============
    # Токены бота
    BOT_TOKEN: Optional[str] = None
    DATABASE_PATH: Optional[str] = "data/banwords.db"

    # Параметры сообщений
    PARSE_MODE: str = "HTML"
    PREFIX: str = "/!.&?"
    LOG_LEVEL: str = "TRACE"

    # Разрешения и логирование
    BOT_EDIT: bool = False
    START_INFO_CONSOLE: bool = True
    START_INFO_TO_FILE: bool = True
    LOG_CONSOLE: bool = True
    LOG_FILE: bool = True
    LOG_DIR: Path = Path('Logs')
    LOG_FILE_INFO: Path = Path('bot_info.log')
    LOG_ROTATION: str = '100 MB'
    LOG_RETENTION: str = '7 days'

    # Вебхук
    WEBHOOK: bool = False
    SECRET_TOKEN: Optional[str] = ''
    WEBHOOK_URL: Optional[str] = None
    WEBAPP_HOST: str = "0.0.0.0"
    WEBAPP_PORT: int = 3131
    LOG_LEVEL: str = "warning"
    ACCES_LOG: bool = False

    # API ключи
    API_KEY: Optional[str] = None
    WEB_API_KEY: Optional[str] = None
    WEATHER_API_KEY: Optional[str] = None

    # Идентификаторы
    OWNER_ID: list[int] = [6751720805]
    ADMIN_ID: list[int] = []

    # Настройки бота
    BOT_NAME: str = "Бот"
    BOT_DESCRIPTION: Optional[str] = None
    BOT_SHORT_DESCRIPTION: Optional[str] = None

    # ============ АВТОКОММЕНТАРИИ В КАНАЛЕ ============

    AUTO_COMMENT_CHANNELS: str = Field(
        default="",
        description="ID каналов через запятую"
    )

    AUTO_COMMENT_TEXT: str = Field(
        default="🔍 <b>Нужна помощь?</b>\n\nИспользуй наш сервис!",
        description="Текст по умолчанию (HTML)"
    )

    AUTO_COMMENT_BUTTON_TEXT: str = Field(
        default="🌐 Искать в Google",
        description="Текст кнопки по умолчанию"
    )

    AUTO_COMMENT_BUTTON_URL: str = Field(
        default="https://www.google.com",
        description="URL кнопки по умолчанию"
    )

    AUTO_COMMENT_PHOTO_URL: str = Field(
        default="https://via.placeholder.com/800x600.png",
        description="URL фото по умолчанию"
    )

    # ================= АДМИНСКИЕ УВЕДОМЛЕНИЯ =================

    # ID чата для уведомлений о банвордах/спаме
    ADMIN_CHAT_ID: Optional[int] = -1002522785068

    # ID топика для уведомлений о банвордах (опционально)
    # Если None - уведомления идут в основной чат (General)
    ADMIN_THREAD_ID: Optional[int] = None  # Например: 12345

    # ================= РЕПОРТЫ =================

    # ID чата для репортов (если None, репорты идут владельцам в ЛС)
    REPORT_CHAT_ID: Optional[int] = ADMIN_CHAT_ID  # Можно тот же чат или другой

    # ID топика для репортов (опционально)
    # Если None - репорты идут в основной чат (General)
    REPORT_THREAD_ID: Optional[int] = None  # ✅ ИСПРАВЛЕНО: было ADMIN_THREAD_ID



    # Права администратора
    ANONYMOUS: bool = False
    MANAGE_CHAT: bool = True
    CHANGE_INFO: bool = True
    PROMOTE_MEMBERS: bool = True
    RESTRICT_MEMBERS: bool = True
    POST_MESSAGE: bool = True
    MANAGE_TOPICS: bool = True
    INVITE_USER: bool = True
    DELETE_MESSAGES: bool = True
    MANAGE_VIDEO_CHATS: bool = True
    EDIT_MESSAGES: bool = True
    PIN_MESSAGE: bool = True
    POST_STORIES: bool = True
    EDIT_STORIES: bool = True
    DELETE_STORIES: bool = True

    # Настройки сообщений
    DISABLE_NOTIFICATION: bool = False
    PROTECT_CONTENT: bool = False
    ALLOW_SENDING_WITHOUT_REPLY: bool = True
    LINK_PREVIEW_IS_DISABLED: bool = False
    LINK_PREVIEW_PREFER_SMALL_MEDIA: bool = False
    LINK_PREVIEW_PREFER_LARGE_MEDIA: bool = True
    LINK_PREVIEW_SHOW_ABOVE_TEXT: bool = True
    SHOW_CAPTION_ABOVE_MEDIA: bool = False

    # улучшения
    ANTI_SPAM: bool = True

    # ================= ВАЛИДАТОРЫ =================
    @field_validator('PARSE_MODE')
    def validate_parse_mode(cls, v: str) -> str:
        allowed_modes: set[str] = {"HTML", "Markdown", "MarkdownV2"}
        if v not in allowed_modes:
            raise ValueError(f"Недопустимый PARSE_MODE. Допустимые: {', '.join(allowed_modes)}")
        return v

    @field_validator('PREFIX')
    def validate_prefix(cls, v: str) -> str:
        cleaned: str = ''.join(dict.fromkeys(v))  # Удаление дубликатов с сохранением порядка
        if len(cleaned) < 1:
            raise ValueError("PREFIX должен содержать хотя бы один символ")
        return cleaned

    @field_validator('LOG_DIR', 'LOG_FILE_INFO', mode='before')
    def validate_paths(cls, v: Any) -> Path:
        return Path(v) if isinstance(v, str) else v

    @field_validator('WEBHOOK_URL')
    def validate_webhook_url(cls, v: Optional[str]) -> Optional[str]:
        if v is None:
            return v
        parsed: ParseResult = urlparse(v)
        if not all([parsed.scheme, parsed.netloc]):
            raise ValueError("Некорректный URL вебхука")
        if parsed.scheme != 'https':
            raise ValueError("WEBHOOK_URL должен использовать HTTPS")
        return v

    @field_validator('BOT_NAME')
    def validate_non_empty(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("Поле не может быть пустым")
        return v

    @model_validator(mode='after')
    def validate_bot_token(self) -> "_Settings":
        if not self.BOT_TOKEN:
            raise ValueError("Требуется BOT_TOKEN для рабочего режима")
        return self

    @model_validator(mode='after')
    def validate_webhook_config(self) -> "_Settings":
        if self.WEBHOOK and not self.WEBHOOK_URL:
            raise ValueError("WEBHOOK_URL обязателен при включенном WEBHOOK")

        # ✅ Генерация SECRET_TOKEN если не установлен
        if self.WEBHOOK and not self.SECRET_TOKEN:
            self.SECRET_TOKEN = token_urlsafe(32)

        return self

    @model_validator(mode='after')
    def validate_logging_paths(self) -> "_Settings":
        if self.LOG_FILE:
            self.LOG_DIR.mkdir(parents=True, exist_ok=True)

        return self

    @model_validator(mode='after')
    def set_dynamic_descriptions(self) -> "_Settings":
        if self.BOT_DESCRIPTION is None:
            self.BOT_DESCRIPTION = f"Ваш помощник в удивительные миры! Prod. by:『@verdise』"
        if self.BOT_SHORT_DESCRIPTION is None:
            self.BOT_SHORT_DESCRIPTION = f"Тех.поддержка: @verdise"
        return self

    # ================= СВОЙСТВА =================
    @property
    def AUTO_COMMENT_CHANNELS_LIST(self) -> list[int]:
        """Преобразует строку ID каналов в список"""
        if not self.AUTO_COMMENT_CHANNELS:
            return []

        try:
            return [
                int(channel_id.strip())
                for channel_id in self.AUTO_COMMENT_CHANNELS.split(",")
                if channel_id.strip()
            ]
        except ValueError:
            from middleware.loggers import logger  # ✅ ДОБАВЬ ИМПОРТ
            logger.error(
                "Неверный формат AUTO_COMMENT_CHANNELS",
                log_type="CONFIG"
            )
            return []

    @property
    def rights(self) -> ChatAdministratorRights:
        """Права администратора бота"""
        return ChatAdministratorRights(
            is_anonymous=self.ANONYMOUS,
            can_manage_chat=self.MANAGE_CHAT,
            can_delete_messages=self.DELETE_MESSAGES,
            can_manage_video_chats=self.MANAGE_VIDEO_CHATS,
            can_restrict_members=self.RESTRICT_MEMBERS,
            can_promote_members=self.PROMOTE_MEMBERS,
            can_change_info=self.CHANGE_INFO,
            can_invite_users=self.INVITE_USER,
            can_post_stories=self.POST_STORIES,
            can_edit_stories=self.EDIT_STORIES,
            can_delete_stories=self.DELETE_STORIES,
            can_post_messages=self.POST_MESSAGE,
            can_edit_messages=self.EDIT_MESSAGES,
            can_pin_messages=self.PIN_MESSAGE,
            can_manage_topics=self.MANAGE_TOPICS,
        )

    @property
    def active_bot_token(self) -> str:
        """Активный токен бота в зависимости от режима"""
        if not self.BOT_TOKEN:
            raise ValueError("Активный токен бота отсутствует")
        return self.BOT_TOKEN

    @property
    def log_dir_absolute(self) -> Path:
        """Абсолютный путь к директории логов"""
        return self.LOG_DIR.absolute()

    @property
    def super_admin_ids(self) -> set[int]:
        """Множество ID суперадминов (для банвордов)"""
        return set(self.OWNER_ID)


# ✅ Единственный экземпляр настроек
settings = _Settings()

# ✅ ОПЦИОНАЛЬНО: Простые константы для обратной совместимости (без дублирования)
# Используются только для удобства импорта, но ссылаются на settings
BOT_TOKEN = settings.active_bot_token
ADMIN_CHAT_ID = settings.ADMIN_CHAT_ID
SUPER_ADMIN_IDS = settings.super_admin_ids

# Экспорт
__all__ = (
    'settings',
    'BOT_TOKEN',
    'ADMIN_CHAT_ID',
    'SUPER_ADMIN_IDS',
)
