from __future__ import annotations

import os
from dataclasses import dataclass
from pathlib import Path

from dotenv import load_dotenv

BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR / ".env")


def _bool(name: str, default: bool) -> bool:
    return os.getenv(name, str(default)).strip().lower() in {"1", "true", "yes", "on"}


def _int(name: str, default: int = 0, minimum: int | None = None) -> int:
    raw = os.getenv(name, str(default)).strip()
    try:
        value = int(raw)
    except ValueError as exc:
        raise RuntimeError(f"{name} harus berupa angka") from exc
    if minimum is not None and value < minimum:
        raise RuntimeError(f"{name} minimal {minimum}")
    return value


def _ids(raw: str) -> set[int]:
    result = set()
    for part in raw.split(","):
        part = part.strip()
        if not part:
            continue
        try:
            result.add(int(part))
        except ValueError as exc:
            raise RuntimeError("ADMIN_IDS harus berisi ID angka dipisahkan koma") from exc
    return result


@dataclass(frozen=True)
class Settings:
    token: str
    admin_ids: set[int]
    channel_post_id: int
    log_channel_id: int
    auto_delete_seconds: int
    database_path: Path
    log_level: str
    protect_content: bool
    broadcast_delay: float


def load_settings() -> Settings:
    token = os.getenv("BOT_TOKEN", "").strip()
    if not token:
        raise RuntimeError("BOT_TOKEN belum diisi di .env")
    admins = _ids(os.getenv("ADMIN_IDS", ""))
    if not admins:
        raise RuntimeError("ADMIN_IDS belum diisi di .env")
    db = Path(os.getenv("DATABASE_PATH", "data/bot.sqlite3"))
    if not db.is_absolute():
        db = BASE_DIR / db
    db.parent.mkdir(parents=True, exist_ok=True)
    try:
        broadcast_delay = max(0.04, float(os.getenv("BROADCAST_DELAY", "0.05")))
    except ValueError as exc:
        raise RuntimeError("BROADCAST_DELAY harus berupa angka desimal") from exc
    return Settings(
        token=token,
        admin_ids=admins,
        channel_post_id=_int("CHANNEL_POST_ID", 0),
        log_channel_id=_int("LOG_CHANNEL_ID", 0),
        auto_delete_seconds=_int("AUTO_DELETE_SECONDS", 7200, minimum=1),
        database_path=db,
        log_level=os.getenv("LOG_LEVEL", "INFO").upper(),
        protect_content=_bool("PROTECT_CONTENT", True),
        broadcast_delay=broadcast_delay,
    )


settings = load_settings()
