import re
import time
from typing import Optional

import regex

from config import Config


STRINGS = {
    "fa": {
        "start": "سلام. من ربات مدیریت گروه هستم.",
        "help": (
            "دستورات اصلی:\n"
            "/ban - بن کاربر با ریپلای یا آیدی عددی\n"
            "/unban - رفع بن\n"
            "/mute [10m|1h|1d] - سکوت کاربر\n"
            "/unmute - رفع سکوت\n"
            "/warn - اخطار به کاربر\n"
            "/warns - مشاهده اخطارها\n"
            "/delwarns - پاک کردن اخطارها\n"
            "/lock links|media|fosh|flood|duplicate|all - قفل‌ها\n"
            "/unlock links|media|fosh|flood|duplicate|all - باز کردن قفل‌ها\n"
            "/close - بستن گروه\n"
            "/open - باز کردن گروه\n"
            "/echo - ارسال پیام از طریق ربات\n"
            "/panel - پنل مدیریت\n"
            "/settings - تنظیمات گروه"
        ),
        "no_permission": "شما اجازه انجام این کار را ندارید.",
        "sponsor_required": "برای استفاده از ربات باید عضو اسپانسرهای زیر شوید.",
        "check_membership": "بررسی عضویت",
        "joined": "عضویت شما تأیید شد.",
        "not_joined": "هنوز عضو همه اسپانسر‌ها نشده‌اید.",
        "done": "انجام شد.",
        "error": "خطایی رخ داد.",
        "user_not_found": "کاربر پیدا نشد. روی پیام ریپلای کنید یا آیدی عددی بفرستید.",
        "cannot_moderate": "این کاربر قابل مدیریت نیست.",
        "banned": "کاربر بن شد.",
        "unbanned": "کاربر از بن خارج شد.",
        "muted": "کاربر سکوت شد.",
        "unmuted": "کاربر از سکوت خارج شد.",
        "warn_added": "یک اخطار ثبت شد.",
        "warn_count": "تعداد اخطارها: {count}",
        "warnings_cleared": "اخطارهای این کاربر پاک شد.",
        "max_warn_action": "به دلیل رسیدن اخطارها به حد مجاز، کاربر محدود شد.",
        "lock_enabled": "قفل {lock} فعال شد.",
        "lock_disabled": "قفل {lock} غیرفعال شد.",
        "invalid_lock": "نوع قفل نامعتبر است.",
        "echo_empty": "متنی برای اکو وجود ندارد.",
        "panel_title": "پنل مدیریت",
        "settings": "تنظیمات",
        "permission_added": "دسترسی {perm} به کاربر داده شد.",
        "permission_removed": "دسترسی {perm} از کاربر گرفته شد.",
        "perm_list": "دسترسی‌های کاربر:",
        "none": "هیچ‌کدام",
        "sponsor_added": "اسپانسر اضافه شد.",
        "sponsor_removed": "اسپانسر حذف شد.",
        "sponsors_list": "اسپانسرهای فعال:",
        "invalid_sponsor": "اسپانسر نامعتبر است یا لینک ندارد.",
        "lang_changed": "زبان ربات تغییر کرد.",
        "group_closed": "گروه بسته شد.",
        "group_opened": "گروه باز شد.",
        "bot_owner_only": "این دستور فقط برای مالک ربات است.",
        "usage_grant": "روش استفاده:\nبا ریپلای: /grant echo\nیا: /grant 123456 echo",
        "usage_sponsor": "روش استفاده:\n/add_sponsor @channel یا /add_sponsor -100123456 [link]",
    },
    "en": {
        "start": "Hello. I am a group management bot.",
        "help": (
            "Main commands:\n"
            "/ban - ban user by reply or numeric ID\n"
            "/unban - unban user\n"
            "/mute [10m|1h|1d] - mute user\n"
            "/unmute - unmute user\n"
            "/warn - warn user\n"
            "/warns - view warnings\n"
            "/delwarns - clear warnings\n"
            "/lock links|media|fosh|flood|duplicate|all - locks\n"
            "/unlock ... - unlock\n"
            "/close - close group\n"
            "/open - open group\n"
            "/echo - echo message\n"
            "/panel - admin panel\n"
            "/settings - group settings"
        ),
        "no_permission": "You do not have permission.",
        "sponsor_required": "To use the bot, join the sponsors below.",
        "check_membership": "Check membership",
        "joined": "Membership confirmed.",
        "not_joined": "You have not joined all sponsors yet.",
        "done": "Done.",
        "error": "An error occurred.",
        "user_not_found": "User not found. Reply to a message or provide numeric ID.",
        "cannot_moderate": "This user cannot be moderated.",
        "banned": "User banned.",
        "unbanned": "User unbanned.",
        "muted": "User muted.",
        "unmuted": "User unmuted.",
        "warn_added": "Warning added.",
        "warn_count": "Warnings: {count}",
        "warnings_cleared": "Warnings cleared.",
        "max_warn_action": "Warning limit reached; user restricted.",
        "lock_enabled": "Lock enabled: {lock}",
        "lock_disabled": "Lock disabled: {lock}",
        "invalid_lock": "Invalid lock type.",
        "echo_empty": "No text to echo.",
        "panel_title": "Admin panel",
        "settings": "Settings",
        "permission_added": "Permission {perm} granted.",
        "permission_removed": "Permission {perm} revoked.",
        "perm_list": "User permissions:",
        "none": "None",
        "sponsor_added": "Sponsor added.",
        "sponsor_removed": "Sponsor removed.",
        "sponsors_list": "Active sponsors:",
        "invalid_sponsor": "Invalid sponsor or missing link.",
        "lang_changed": "Language changed.",
        "group_closed": "Group closed.",
        "group_opened": "Group opened.",
        "bot_owner_only": "Only bot owner can use this command.",
        "usage_grant": "Usage:\nReply: /grant echo\nOr: /grant 123456 echo",
        "usage_sponsor": "Usage:\n/add_sponsor @channel or /add_sponsor -100123456 [link]",
    },
}


def t(key: str, lang: str = "fa", **kwargs) -> str:
    lang = lang if lang in STRINGS else "en"
    text = STRINGS.get(lang, STRINGS["en"]).get(key, key)
    try:
        return text.format(**kwargs)
    except Exception:
        return text


class TTLCache:
    def __init__(self, default_ttl: int = 120):
        self._data = {}
        self._expiry = {}
        self.default_ttl = default_ttl

    def get(self, key: str):
        now = time.time()
        if key in self._data and self._expiry.get(key, 0) > now:
            return self._data[key]
        self._data.pop(key, None)
        self._expiry.pop(key, None)
        return None

    def set(self, key: str, value, ttl: Optional[int] = None):
        self._data[key] = value
        self._expiry[key] = time.time() + (ttl or self.default_ttl)


def normalize_text(text: str) -> str:
    if not text:
        return ""

    text = text.lower()

    replacements = {
        "ي": "ی",
        "ی": "ی",
        "ك": "ک",
        "ک": "ک",
        "ة": "ه",
        "أ": "ا",
        "إ": "ا",
        "آ": "ا",
        "ؤ": "و",
        "ئ": "ی",
        "ى": "ی",
    }

    for old, new in replacements.items():
        text = text.replace(old, new)

    # Remove diacritics
    text = regex.sub(r"\p{M}+", "", text)

    # Remove ZWNJ
    text = text.replace("‌", "")

    # Remove punctuation but keep letters/numbers/spaces
    text = regex.sub(r"[^\p{L}\p{N}\s]", " ", text)

    # Collapse spaces
    text = regex.sub(r"\s+", " ", text).strip()

    return text


URL_RE = regex.compile(r"(https?://|www\.|t\.me/|telegram\.me/|wa\.me/|instagram\.com/)", regex.IGNORECASE)
USERNAME_RE = regex.compile(r"@([A-Za-z0-9_]{5,32})")
EMOJI_RE = regex.compile(r"\p{Extended_Pictographic}")


def contains_url(text: str) -> bool:
    if not text:
        return False
    return bool(URL_RE.search(text))


def contains_username(text: str) -> bool:
    if not text:
        return False
    return bool(USERNAME_RE.search(text))


def count_emoji(text: str) -> int:
    if not text:
        return 0
    return len(EMOJI_RE.findall(text))


def parse_duration(text: str) -> Optional[int]:
    """
    Parse durations like:
    30s, 10m, 2h, 1d
    Returns seconds.
    """
    if not text:
        return None

    text = text.strip().lower()
    match = re.match(r"^(\d+)([smhd])$", text)
    if not match:
        return None

    value = int(match.group(1))
    unit = match.group(2)

    units = {
        "s": 1,
        "m": 60,
        "h": 3600,
        "d": 86400,
    }

    return value * units.get(unit, 1)


def format_duration(seconds: int) -> str:
    if seconds <= 0:
        return "0s"

    days = seconds // 86400
    seconds %= 86400
    hours = seconds // 3600
    seconds %= 3600
    minutes = seconds // 60
    seconds %= 60

    parts = []
    if days:
        parts.append(f"{days}d")
    if hours:
        parts.append(f"{hours}h")
    if minutes:
        parts.append(f"{minutes}m")
    if seconds:
        parts.append(f"{seconds}s")

    return " ".join(parts)


def get_lang(chat_id, user, settings_service=None) -> str:
    if settings_service and chat_id:
        lang = settings_service.get(chat_id, "lang")
        if lang in ("fa", "en"):
            return lang

    if user and getattr(user, "language_code", None):
        if user.language_code.lower().startswith("fa"):
            return "fa"
        if user.language_code.lower().startswith("en"):
            return "en"

    return Config.DEFAULT_LANG if Config.DEFAULT_LANG in ("fa", "en") else "en"


def get_args(message):
    if not message.text:
        return []
    parts = message.text.split()
    return parts[1:] if len(parts) > 1 else []