#========================================
#               ایمپورت‌ها
#========================================
from telethon import events
from telethon.tl.functions.account import UpdateProfileRequest
from datetime import datetime
import asyncio
from telethon import events, Button
import httpx
from deep_translator import GoogleTranslator
import subprocess
import os
try:
    from PIL import Image
    PIL_AVAILABLE = True
except:
    PIL_AVAILABLE = False
import requests
from telethon.tl.functions.users import GetFullUserRequest
from telethon.tl.functions.photos import UploadProfilePhotoRequest
from telethon.errors import FloodWaitError
try:
    import phonenumbers
    from phonenumbers import geocoder, carrier, timezone
    PHONE_AVAILABLE = True
except:
    PHONE_AVAILABLE = False
import sqlite3
from telethon.tl.functions.channels import LeaveChannelRequest
from telethon.tl.functions.contacts import BlockRequest, UnblockRequest
import sqlite3
#========================================
#               متغیرها
#========================================
clock_font_type = 1
bio_font_type = 1


#========================================
#               فونت‌ها
#========================================
FONTS = {
    1: str.maketrans("0123456789.", "𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡."),
    2: str.maketrans("0123456789.", "₀₁₂₃₄₅₆₇₈₉."),
    3: str.maketrans("0123456789.", "０１２３４５６۷۸۹．"),
    4: str.maketrans("0123456789.", "⓪①②③④⑤⑥⑦⑧⑨."),
    5: str.maketrans("0123456789.", "①②③④⑤⑥⑦⑧⑨⓪."),
    6: str.maketrans("0123456789.", "𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫."),
    7: str.maketrans("0123456789.", "𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡﹒"),
    8: str.maketrans("0123456789.", "𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿."),
    9: str.maketrans("0123456789.", "❶❷❸❹❺❻❼❽❾⓿."),
    10: str.maketrans("0123456789.", "0123456789.")
}

def make_time(font_id):
    raw = datetime.now().strftime("%H.%M")
    return raw.translate(FONTS.get(font_id, FONTS[1]))


#========================================
#           شروع سلف‌بات
#========================================
async def start_selfbot(client, phone):
    my_id = (await client.get_me()).id
    global current_client
    current_client = client

    print(f"SELF BOT STARTED ON {phone}")

    from Selfing2 import setup_reactions
    await setup_reactions(client, my_id, phone)
    #========= تست =========
    @client.on(events.NewMessage(pattern=r'^\.تست$'))
    async def test_handler(event):
        if event.sender_id != my_id:
            return
        await event.reply("سلف فعاله ✔️")

    #========= سلام =========
    @client.on(events.NewMessage(pattern=r'^\.سلام$'))
    async def salam_handler(event):
        if event.sender_id != my_id:
            return
        await event.reply("علیک سلام 😎🔥")

#========= ساعت =========
    clock_enabled = False
    bio_clock_enabled = False
    original_name = None
    original_bio = None

    async def clock_loop():
        nonlocal original_name, clock_enabled
        me = await client.get_me()
        if original_name is None:
            original_name = me.first_name
        while clock_enabled:
            try:
                await client(UpdateProfileRequest(
                    first_name=f"{original_name} {make_time(clock_font_type)}"
                ))
            except Exception as e:
                print(f"clock_loop error: {e}")
            await asyncio.sleep(70)

    async def bio_loop():
        nonlocal original_bio, bio_clock_enabled
        me = await client.get_me()
        if original_bio is None:
            original_bio = getattr(me, "about", "")
        while bio_clock_enabled:
            try:
                await client(UpdateProfileRequest(
                    about=f"{original_bio} {make_time(bio_font_type)}"
                ))
            except Exception as e:
                print(f"bio_loop error: {e}")
            await asyncio.sleep(70)

    @client.on(events.NewMessage(pattern=r'^\.ساعت روشن$'))
    async def clock_on(event):
        nonlocal clock_enabled
        if event.sender_id != my_id:
            return
        clock_enabled = True
        await event.edit("● ساعت روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
        asyncio.create_task(clock_loop())

    @client.on(events.NewMessage(pattern=r'^\.ساعت خاموش$'))
    async def clock_off(event):
        nonlocal clock_enabled, original_name
        if event.sender_id != my_id:
            return
        clock_enabled = False
        if original_name:
            await client(UpdateProfileRequest(first_name=original_name))
        await event.edit("● ساعت خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.ساعت بیو روشن$'))
    async def bio_on(event):
        nonlocal bio_clock_enabled
        if event.sender_id != my_id:
            return
        bio_clock_enabled = True
        await event.edit("● ساعت بیو روشن شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
        asyncio.create_task(bio_loop())

    @client.on(events.NewMessage(pattern=r'^\.ساعت بیو خاموش$'))
    async def bio_off(event):
        nonlocal bio_clock_enabled, original_bio
        if event.sender_id != my_id:
            return
        bio_clock_enabled = False
        if original_bio:
            await client(UpdateProfileRequest(about=original_bio))
        await event.edit("● ساعت بیو خاموش شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.فونت ساعت (\d+)$'))
    async def set_clock_font(event):
        if event.sender_id != my_id:
            return
        global clock_font_type
        clock_font_type = int(event.pattern_match.group(1))
        await event.edit(f"فونت ساعت اسم شد {clock_font_type}")

    @client.on(events.NewMessage(pattern=r'^\.فونت ساعت بیو (\d+)$'))
    async def set_bio_font(event):
        if event.sender_id != my_id:
            return
        global bio_font_type
        bio_font_type = int(event.pattern_match.group(1))
        await event.edit(f"فونت ساعت بیو شد {bio_font_type}")

#========= قفل پیوی =========
    pv_lock_enabled = False
    me = await client.get_me()
    my_id = me.id

    @client.on(events.NewMessage(pattern=r'^\.قفل پیوی روشن$'))
    async def pv_lock_on(event):
        nonlocal pv_lock_enabled
        if event.sender_id != my_id:
            return
        pv_lock_enabled = True
        await event.delete()
        await client.send_message(event.chat_id, "● قفل پیوی روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.قفل پیوی خاموش$'))
    async def pv_lock_off(event):
        nonlocal pv_lock_enabled
        if event.sender_id != my_id:
            return
        pv_lock_enabled = False
        await event.delete()
        await client.send_message(event.chat_id, "● قفل پیوی خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(incoming=True, func=lambda e: e.is_private))
    async def pv_lock_handler(event):
        if pv_lock_enabled:
            await event.delete()

#========= مدیا تایم =========
    media_time_enabled = False

    @client.on(events.NewMessage(pattern=r'^\.مدیا تایم روشن$'))
    async def media_time_on(event):
        nonlocal media_time_enabled
        if event.sender_id != my_id:
            return
        media_time_enabled = True
        await event.delete()
        await client.send_message(event.chat_id, "● مدیا تایم روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.مدیا تایم خاموش$'))
    async def media_time_off(event):
        nonlocal media_time_enabled
        if event.sender_id != my_id:
            return
        media_time_enabled = False
        await event.delete()
        await client.send_message(event.chat_id, "● مدیا تایم خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(incoming=True))
    async def media_time_handler(event):
        if not media_time_enabled:
            return
        msg = event.message
        if not msg.media:
            return
        # فقط عکس‌های زماندار (time-limited)
        if not getattr(msg.media, 'ttl_seconds', None):
            return
        # دانلود و ارسال به پیام‌های ذخیره‌شده
        file = await client.download_media(msg)
        await client.send_file("me", file)

#========= اسپم =========
    @client.on(events.NewMessage(pattern=r'^\.اسپم (\d+) (.+)$'))
    async def spam_handler(event):
        if event.sender_id != my_id:
            return
        count = int(event.pattern_match.group(1))
        text = event.pattern_match.group(2)
        await event.delete()
        for i in range(count):
            try:
                await event.respond(text)
                await asyncio.sleep(0.3)
            except Exception as e:
                break

#========= پنل =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.پنل$'))
    async def panel(event):
        if event.sender_id != my_id:
            return
        await event.delete()
        results = await client.inline_query("@Helpervidalbot", "panel")
        msg = await results[0].click(event.chat_id)

        # منتظر بمانید تا کاربر دکمه بستن رو بزنه
        await asyncio.sleep(1)

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ماشین حساب$'))
    async def calc_handler(event):
        if event.sender_id != my_id:
            return
        await event.delete()
        results = await client.inline_query("@Helpervidalbot", "calc")
        msg = await results[0].click(event.chat_id)

        # منتظر بمانید تا کاربر دکمه بستن رو بزنه
        await asyncio.sleep(1)

#========= اطلاعات =========
    info_enabled = True   # این قابلیت همیشه روشنه، ولی ساختار مثل مدیا تایم می‌زنم

    @client.on(events.NewMessage(pattern=r'^\.اطلاعات روشن$'))
    async def info_on(event):
        nonlocal info_enabled
        if event.sender_id != my_id:
            return
        info_enabled = True
        await event.delete()
        await client.send_message(event.chat_id, "● اطلاعات روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.اطلاعات خاموش$'))
    async def info_off(event):
        nonlocal info_enabled
        if event.sender_id != my_id:
            return
        info_enabled = False
        await event.delete()
        await client.send_message(event.chat_id, "● اطلاعات خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.اطلاعات$'))
    async def info_handler(event):
        nonlocal info_enabled
        if not info_enabled:
            return

        if event.sender_id != my_id:
            return

        if not event.is_reply:
            await event.reply("❌ باید روی پیام کاربر ریپلای بزنی")
            return

        reply = await event.get_reply_message()
        user = await client.get_entity(reply.sender_id)

        # تعداد عکس‌های پروفایل
        photos = await client.get_profile_photos(user)
        photo_count = len(photos)

        text = f"""
● **اطلاعات کاربر**

● **اسم:** {user.first_name or '—'}
● **آیدی عددی:** `{user.id}`
● **یوزرنیم:** @{user.username if user.username else 'ندارد'}
● **تعداد پروفایل:** {photo_count}

● **ربات:** {'بله' if user.bot else 'خیر'}
● **پریمیوم:** {'بله' if getattr(user, 'premium', False) else 'خیر'}
● **اسکم:** {'بله' if getattr(user, 'scam', False) else 'خیر'}
● **فیک:** {'بله' if getattr(user, 'fake', False) else 'خیر'}

● **لینک پروفایل:** tg://user?id={user.id}
"""

        await event.reply(text, parse_mode="Markdown")

#========= ترجمه =========

    @client.on(events.NewMessage(pattern=r'^\.ترجمه$'))
    async def translate_handler(event):
        if event.sender_id != my_id:
            return

        if not event.is_reply:
            await event.reply("❌ باید روی پیام کاربر ریپلای بزنی")
            return

        reply = await event.get_reply_message()
        text = reply.message

        if not text:
            await event.reply("❌ این پیام متن نداره")
            return

        try:
            url = "https://translate.googleapis.com/translate_a/single"
            params = {
                "client": "gtx",
                "sl": "auto",   # تشخیص خودکار زبان
                "tl": "fa",     # ترجمه به فارسی
                "dt": "t",
                "q": text
            }

            r = httpx.get(url, params=params)
            result = r.json()

            translated = result[0][0][0]
            src_lang = result[2]

            msg = f"""
● **ترجمه انجام شد**

● **زبان تشخیص داده‌شده:** {src_lang}
● **متن ترجمه‌شده:**
{translated}
"""

            await event.reply(msg, parse_mode="Markdown")

        except Exception as e:
            await event.reply(f"❌ خطا در ترجمه: {e}")

#========= متن انگلیسی =========
    english_mode = False

    @client.on(events.NewMessage(pattern=r'^\.متن انگلیسی روشن$'))
    async def english_on(event):
        nonlocal english_mode
        if event.sender_id != my_id:
            return
        english_mode = True
        await event.delete()
        await client.send_message(event.chat_id, "● متن انگلیسی روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(pattern=r'^\.متن انگلیسی خاموش$'))
    async def english_off(event):
        nonlocal english_mode
        if event.sender_id != my_id:
            return
        english_mode = False
        await event.delete()
        await client.send_message(event.chat_id, "● متن انگلیسی خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")

    @client.on(events.NewMessage(outgoing=True))
    async def english_auto(event):
        nonlocal english_mode
        if not english_mode:
            return

        text = event.message.message
        if not text:
            return

        try:
            translated = GoogleTranslator(source='auto', target='en').translate(text)

            # حذف متن‌های اضافی deep-translator
            if translated:
                translated = translated.replace("Clear English text", "").strip()

            # اگر ترجمه خالی بود → پیام جدید ارسال کن
            if not translated:
                await client.send_message(event.chat_id, "⚠ ترجمه انجام شد اما متن خالی بود.")
                return

            # تلاش برای ادیت پیام
            try:
                await client.edit_message(event.chat_id, event.id, translated)
            except:
                # اگر ادیت نشد → پیام جدید ارسال کن
                await client.send_message(event.chat_id, translated)

        except Exception as e:
            await event.reply(f"❌ خطا در ترجمه: {e}")

#========= ساخت گیف =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ساخت گیف$'))
    async def make_gif_handler(event):
        if not event.is_reply:
            await event.edit("روی یک فیلم یا عکس ریپلای کنید!")
            return
        replied = await event.get_reply_message()
        if replied.video:
            await event.edit("● در حال ساخت گیف♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
            path = await replied.download_media()
            if path:
                output_path = path.replace(".mp4", ".gif")
                try:
                    cmd = ['ffmpeg', '-i', path, '-an', '-vf', 'fps=10,scale=320:-1', '-loop', '0', '-y', output_path]
                    subprocess.run(cmd, check=True, capture_output=True)
                    await client.send_file(event.chat_id, output_path, caption="🎬 گیف بیصدا ساخته شد!")
                    os.remove(path)
                    os.remove(output_path)
                    await event.edit("● گیف ساخته شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
                    await asyncio.sleep(2)
                    await event.delete()
                except Exception as e:
                    await event.edit(f"❌ خطا در ساخت گیف: {e}")
            else:
                await event.edit("❌ خطا در دانلود!")
        elif replied.photo:
            await event.edit("● در حال ساخت گیف ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
            path = await replied.download_media()
            if path and PIL_AVAILABLE:
                try:
                    img = Image.open(path)
                    output_path = path.replace(".jpg", ".gif").replace(".png", ".gif")
                    frames = [img.copy() for _ in range(10)]
                    frames[0].save(output_path, save_all=True, append_images=frames[1:], duration=100, loop=0)
                    await client.send_file(event.chat_id, output_path, caption="🎬 گیف ساخته شد!")
                    os.remove(path)
                    os.remove(output_path)
                    await event.edit("● گیف ساخته شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
                    await asyncio.sleep(2)
                    await event.delete()
                except Exception as e:
                    await event.edit(f"❌ خطا در ساخت گیف: {e}")
            else:
                await event.edit("❌ کتابخانه PIL نصب نیست!")
        else:
            await event.edit("❌ روی فیلم یا عکس ریپلای کنید!")

    #========= عکس به استیکر =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.عکس به استیکر$'))
    async def photo_to_sticker_handler(event):
        if not event.is_reply:
            await event.edit("❌ روی یک عکس ریپلای کنید!")
            return
        replied = await event.get_reply_message()
        if replied.photo:
            await event.edit("● در حال ساخت استیکر ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
            path = await replied.download_media()
            if path and PIL_AVAILABLE:
                try:
                    img = Image.open(path)
                    img.thumbnail((512, 512))
                    new_img = Image.new("RGBA", (512, 512), (0, 0, 0, 0))
                    x = (512 - img.width) // 2
                    y = (512 - img.height) // 2
                    new_img.paste(img, (x, y))
                    output_path = path.replace(".jpg", ".webp").replace(".png", ".webp")
                    new_img.save(output_path, "WEBP")
                    await client.send_file(event.chat_id, output_path, force_document=False)
                    os.remove(path)
                    os.remove(output_path)
                    await event.edit("● استیکر ساخته شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
                    await asyncio.sleep(2)
                    await event.delete()
                except Exception as e:
                    await event.edit(f"❌ خطا در ساخت استیکر: {e}")
            else:
                await event.edit("❌ کتابخانه PIL نصب نیست یا عکس نامعتبر!")
        else:
            await event.edit("❌ روی عکس ریپلای کنید!")

    #========= فیلم به استیکر =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.فیلم به استیکر$'))
    async def video_to_sticker_handler(event):
        if not event.is_reply:
            await event.edit("❌ روی یک فیلم ریپلای کنید!")
            return
        replied = await event.get_reply_message()
        if replied.video:
            await event.edit("● در حال ساخت استیکر ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
            path = await replied.download_media()
            if path:
                output_path = path.replace(".mp4", ".webp")
                try:
                    cmd = ['ffmpeg', '-i', path, '-vf', 'fps=10,scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2', '-loop', '0', '-y', output_path]
                    subprocess.run(cmd, check=True, capture_output=True)
                    await client.send_file(event.chat_id, output_path, force_document=False)
                    os.remove(path)
                    os.remove(output_path)
                    await event.edit("● استیکر ساخته شد ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
                    await asyncio.sleep(2)
                    await event.delete()
                except Exception as e:
                    await event.edit(f"❌ خطا در ساخت استیکر متحرک: {e}")
            else:
                await event.edit("❌ خطا در دانلود!")
        else:
            await event.edit("❌ روی فیلم ریپلای کنید!")

#========= کپی پروفایل =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.کپی پروفایل$'))
    async def clone_profile_handler(event):
        if not event.is_reply:
            await event.edit("❌ روی پیام کاربر ریپلای کنید!")
            return
        replied = await event.get_reply_message()
        target_user = replied.sender_id
        try:
            user = await client.get_entity(target_user)
            await event.edit("● در حال کپی پروفایل ♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡 ●")
            try:
                full_user = await client(GetFullUserRequest(id=user.id))
                about = full_user.full_user.about if full_user and full_user.full_user else ""
            except:
                about = ""
            try:
                await client(UpdateProfileRequest(
                    first_name=user.first_name or "",
                    last_name=user.last_name or "",
                    about=about
                ))
            except Exception as e:
                await event.edit(f"⚠️ خطا در کپی نام: {e}")
            try:
                photos = await client.get_profile_photos(user.id, limit=1)
                if photos:
                    photo = await client.download_media(photos[0])
                    if photo:
                        await client(UploadProfilePhotoRequest(
                            file=await client.upload_file(photo)
                        ))
                        os.remove(photo)
            except Exception as e:
                await event.edit(f"⚠️ خطا در کپی عکس: {e}")
            await event.edit(f"●پروفایل {user.first_name}کپی شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
            await asyncio.sleep(2)
            await event.delete()
        except FloodWaitError as e:
            await event.edit(f"❌ محدودیت تلگرام! {e.seconds} ثانیه صبر کنید...")
        except Exception as e:
            await event.edit(f"❌ خطا در کپی پروفایل: {e}")

    #========= چک شماره =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.چک شماره (.+)$'))
    async def check_number_handler(event):
        number = event.pattern_match.group(1)
        number = number.replace(" ", "").replace("-", "").replace("(", "").replace(")", "")
        if number.startswith("+"):
            full_number = number
        elif number.startswith("0"):
            full_number = "+98" + number[1:]
        elif number.startswith("98"):
            full_number = "+" + number
        elif len(number) == 10 and number.startswith("9"):
            full_number = "+98" + number
        else:
            await event.edit("❌ فرمت شماره نامشخص!")
            return
        await event.edit(f"●درحال بررسی شماره {full_number}♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
        try:
            if PHONE_AVAILABLE:
                parsed = phonenumbers.parse(full_number, None)
                is_valid = phonenumbers.is_valid_number(parsed)
                country = geocoder.description_for_number(parsed, "fa")
                operator = carrier.name_for_number(parsed, "fa")
                time_zones = timezone.time_zones_for_number(parsed)
            else:
                is_valid = True
                country = "نامشخص"
                operator = "نامشخص"
                time_zones = []

            user_id = "نامشخص"
            first_name = "نامشخص"
            last_name = ""
            username = "ندارد"
            creation_estimate = "نامشخص"

            try:
                result = await client(
                    functions.contacts.ImportContactsRequest([
                        types.InputPhoneContact(
                            client_id=0,
                            phone=full_number,
                            first_name="temp",
                            last_name=""
                        )
                    ])
                )
                if result.users:
                    user = result.users[0]
                    user_id = user.id
                    first_name = user.first_name or "نامشخص"
                    last_name = user.last_name or ""
                    username = user.username or "ندارد"
                    if user_id > 1000000000:
                        creation_estimate = "جدید (بعد از 2016)"
                    elif user_id > 100000000:
                        creation_estimate = "متوسط (2014-2016)"
                    else:
                        creation_estimate = "قدیمی (قبل از 2014)"
                    await client(
                        functions.contacts.DeleteContactsRequest(id=[user])
                    )
            except:
                pass

            name_display = first_name
            if last_name:
                name_display += " " + last_name

            text = f"""📱 اطلاعات شماره {full_number}

┏━━━━━━━━━━━━━━━━━┓
┃ ● اطلاعات شماره:
┃    شماره: {full_number}
┃    ● اعتبار: {'✅ معتبر' if is_valid else '❌ نامعتبر'}
┃    ● کشور: {country or 'نامشخص'}
┃    ● اپراتور: {operator or 'نامشخص'}
┃    ● منطقه زمانی: {', '.join(time_zones) if time_zones else 'نامشخص'}
┗━━━━━━━━━━━━━━━━━┛"""

            await event.edit(text)
        except Exception as e:
            await event.edit(f"❌ خطا: {e}")
#========= ترک کانال =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ترک کانال (\d+)$'))
    async def leave_channels(event):
        if event.sender_id != my_id:
            return
        count = int(event.pattern_match.group(1))
        await event.edit(f"●درحال ترک{count}کانال♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

        left_count = 0
        try:
            dialogs = await client.get_dialogs(limit=200)
            for dialog in dialogs:
                if left_count >= count:
                    break
                if dialog.is_channel and not dialog.entity.broadcast:
                    try:
                        await client(LeaveChannelRequest(dialog.entity))
                        left_count += 1
                        await asyncio.sleep(0.5)
                    except:
                        pass
        except Exception as e:
            await event.edit(f"❌ خطا: {e}")
            return

        await event.edit(f"●ترک{left_count}کانال انجام شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    #========= ترک گروه =========
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ترک گروه (\d+)$'))
    async def leave_groups(event):
        if event.sender_id != my_id:
            return
        count = int(event.pattern_match.group(1))
        await event.edit(f"●درحال ترک{count}گروه♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

        left_count = 0
        try:
            dialogs = await client.get_dialogs(limit=200)
            for dialog in dialogs:
                if left_count >= count:
                    break
                if dialog.is_group:
                    try:
                        await client(LeaveChannelRequest(dialog.entity))
                        left_count += 1
                        await asyncio.sleep(0.5)
                    except:
                        pass
        except Exception as e:
            await event.edit(f"❌ خطا: {e}")
            return

        await event.edit(f"●ترک{left_count}گروه انجام شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

#==================== دیتابیس عضویت اجباری ====================

    JOIN_DB = "join_force.db"

    def init_join_db():
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("""
            CREATE TABLE IF NOT EXISTS joinforce (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                link TEXT
            )
        """)
        c.execute("""
            CREATE TABLE IF NOT EXISTS settings (
                key TEXT PRIMARY KEY,
                value TEXT
            )
        """)
        conn.commit()
        conn.close()

    init_join_db()

    def jf_add(link):
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("INSERT INTO joinforce (link) VALUES (?)", (link,))
        conn.commit()
        conn.close()

    def jf_delete(link):
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("DELETE FROM joinforce WHERE link = ?", (link,))
        conn.commit()
        conn.close()

    def jf_list():
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("SELECT link FROM joinforce")
        r = c.fetchall()
        conn.close()
        return [i[0] for i in r]

    def jf_set(key, value):
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value))
        conn.commit()
        conn.close()

    def jf_get(key):
        conn = sqlite3.connect(JOIN_DB)
        c = conn.cursor()
        c.execute("SELECT value FROM settings WHERE key = ?", (key,))
        r = c.fetchone()
        conn.close()
        return r[0] if r else None


    #==================== دستورات عضویت اجباری ====================

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.تنظیم عضویت اجباری$'))
    async def jf_set_handler(event):
        if not event.is_reply:
            await event.edit("⚠باید روی لینک ریپلای بزنی!")
            return

        reply = await event.get_reply_message()
        link = reply.message.strip()

        if not ("t.me/" in link or "telegram.me/" in link):
            await event.edit("⚠این لینک تلگرام نیست!")
            return

        jf_add(link)
        await event.edit("●عضویت اجباری تنظیم شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")


    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.حذف عضویت اجباری$'))
    async def jf_del_handler(event):
        if not event.is_reply:
            await event.edit("⚠باید روی لینک ریپلای بزنی!")
            return

        reply = await event.get_reply_message()
        link = reply.message.strip()

        jf_delete(link)
        await event.edit("●عضویت اجباری حذف شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")


    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.عضویت اجباری روشن$'))
    async def jf_on(event):
        jf_set("force_join", "ON")
        await event.edit("●عضویت اجباری روشن شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")


    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.عضویت اجباری خاموش$'))
    async def jf_off(event):
        jf_set("force_join", "OFF")
        await event.edit("●عضویت اجباری خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")


    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.لیست عضویت اجباری$'))
    async def jf_list_handler(event):
        lst = jf_list()
        if not lst:
            await event.edit("هیچ لینکی تنظیم نشده!")
            return

        msg = "لیست لینک‌های عضویت اجباری:\n\n"
        for i in lst:
            msg += f"• {i}\n"

        await event.edit(msg)


    #==================== فیلتر پیام‌های ورودی ====================

    @client.on(events.NewMessage(incoming=True))
    async def jf_filter(event):
        if jf_get("force_join") != "ON":
            return

        uid = event.sender_id
        if uid == my_id:
            return

        links = jf_list()
        if not links:
            return

        for link in links:
            try:
                chat = link.split("/")[-1]
                member = await client.get_permissions(chat, uid)

                if member is None:
                    await event.delete()
                    await client.send_message(
                        uid,
                        f"برای پیام دادن لطفاً عضو شوید:\n{link}"
                    )
                    return

            except:
                await event.delete()
                await client.send_message(
                    uid,
                    f"برای پیام دادن لطفاً عضو شوید:\n{link}"
                )
                return

#==================== دیتابیس فوش‌ها (برای هر کاربر جدا) ====================

    FOSH_DB = "fosh.db"

    def init_fosh_db():
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("""
            CREATE TABLE IF NOT EXISTS fosh (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                text TEXT
            )
        """)
        conn.commit()
        conn.close()

    init_fosh_db()

    # اضافه کردن فوش برای یک کاربر
    def fosh_add(user_id, text):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("INSERT INTO fosh (user_id, text) VALUES (?, ?)", (user_id, text))
        conn.commit()
        conn.close()

    # گرفتن همه فوش‌های یک کاربر
    def fosh_get_all(user_id):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("SELECT id, text FROM fosh WHERE user_id = ?", (user_id,))
        r = c.fetchall()
        conn.close()
        return r

    # حذف یک فوش خاص
    def fosh_delete(user_id, fid):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("DELETE FROM fosh WHERE user_id = ? AND id = ?", (user_id, fid))
        conn.commit()
        conn.close()

    # پاک کردن همه فوش‌های یک کاربر
    def fosh_clear(user_id):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("DELETE FROM fosh WHERE user_id = ?", (user_id,))
        conn.commit()
        conn.close()

    # گرفتن یک فوش رندوم برای کاربر
    def fosh_random(user_id):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("SELECT text FROM fosh WHERE user_id = ? ORDER BY RANDOM() LIMIT 1", (user_id,))
        r = c.fetchone()
        conn.close()
        return r[0] if r else "🔥"

    # شمارش فوش‌های کاربر
    def fosh_count(user_id):
        conn = sqlite3.connect(FOSH_DB)
        c = conn.cursor()
        c.execute("SELECT COUNT(*) FROM fosh WHERE user_id = ?", (user_id,))
        r = c.fetchone()[0]
        conn.close()
        return r
#==================== دیتابیس لیست اتکر ====================
    ATKER_DB = "atker.db"

    def init_atker_db():
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("""
            CREATE TABLE IF NOT EXISTS mentions (
                chat_id INTEGER,
                user_id INTEGER,
                username TEXT
            )
        """)
        c.execute("""
            CREATE TABLE IF NOT EXISTS settings (
                key TEXT PRIMARY KEY,
                value TEXT
            )
        """)
        conn.commit()
        conn.close()

    init_atker_db()

    # اضافه کردن کاربر به لیست اتکر
    def atker_add_mention(chat_id, user_id, username):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("INSERT INTO mentions (chat_id, user_id, username) VALUES (?, ?, ?)",
                  (chat_id, user_id, username))
        conn.commit()
        conn.close()

    # حذف کاربر از لیست اتکر
    def atker_remove_mention(chat_id, user_id):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("DELETE FROM mentions WHERE chat_id = ? AND user_id = ?", (chat_id, user_id))
        conn.commit()
        conn.close()

    # گرفتن لیست اتکر
    def atker_get_mentions(chat_id):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("SELECT user_id, username FROM mentions WHERE chat_id = ?", (chat_id,))
        r = c.fetchall()
        conn.close()
        return r

    # پاک کردن کل لیست اتکر
    def atker_clear_mentions(chat_id):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("DELETE FROM mentions WHERE chat_id = ?", (chat_id,))
        conn.commit()
        conn.close()

    # تنظیمات اتکر (تایمر، ایموجی، فعال/غیرفعال)
    def atker_set(key, value):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value))
        conn.commit()
        conn.close()

    # گرفتن تنظیمات اتکر
    def atker_get(key, default=None):
        conn = sqlite3.connect(ATKER_DB)
        c = conn.cursor()
        c.execute("SELECT value FROM settings WHERE key = ?", (key,))
        r = c.fetchone()
        conn.close()
        return r[0] if r else default
#==================== هندلر فوش‌ها ====================

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک فوش (.+)$'))
    async def add_fosh(event):
        owner = event.sender_id
        text = event.pattern_match.group(1).strip()
        fosh_add(owner, text)
        await event.edit(f"●فوش اضافه شد(تعداد: {fosh_count(owner)})♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک لیست فوش$'))
    async def list_fosh(event):
        owner = event.sender_id
        fl = fosh_get_all(owner)

        if not fl:
            await event.edit("لیست فوش‌ها خالیه!")
            return

        lines = []
        for fid, txt in fl:
            if not txt or txt.strip() == "":
                continue

            txt = txt.replace("\ufeff", "").replace("\u200b", "").strip()

            try:
                txt.encode("utf-8")
            except:
                continue

            if txt == "":
                continue

            lines.append(f"{fid}. {txt}")

        if not lines:
            await event.edit("هیچ فوش سالمی پیدا نشد!")
            return

        # ساخت پیام نهایی با محدودیت 3500 کاراکتر
        msg = "لیست فوش‌ها:\n\n"
        for line in lines:
            if len(msg) + len(line) + 2 > 3500:
                msg += "\nتعداد فوش‌ها زیاد بود، بقیه نمایش داده نشد."
                break
            msg += line + "\n"

        await event.edit(msg)

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک حذف فوش (.+)$'))
    async def delete_fosh(event):
        owner = event.sender_id
        fid = event.pattern_match.group(1).strip()

        try:
            fid = int(fid)
        except:
            await event.edit("ID معتبر نیست!")
            return

        all_f = fosh_get_all(owner)
        if not any(f[0] == fid for f in all_f):
            await event.edit("همچین فوشی وجود نداره!")
            return

        fosh_delete(owner, fid)
        await event.edit(f"●فوش{fid}حذف شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک پاک فوش$'))
    async def clear_fosh(event):
        owner = event.sender_id
        count = fosh_count(owner)

        if count == 0:
            await event.edit("لیست فوش‌ها خالیه")
            return

        fosh_clear(owner)
        await event.edit(f"●{count}فوش پاک شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک فوش رندوم$'))
    async def random_fosh(event):
        owner = event.sender_id
        await event.edit(f"فوش تصادفی:\n{fosh_random(owner)}")
#==================== اضافه کردن فوش از فایل ریپلای‌شده ====================

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک فوش فایل$'))
    async def atker_fosh_file(event):
        owner_id = event.sender_id

        if not event.is_reply:
            await event.edit("باید روی فایل ریپلای بزنی!")
            return

        reply = await event.get_reply_message()

        if not reply.document:
            await event.edit("این پیام فایل نیست!")
            return

        try:
            file_path = await reply.download_media()
        except Exception as e:
            await event.edit(f"خطا در دانلود فایل: {e}")
            return

        added = 0
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                for line in f:
                    line = line.strip()
                    if line:
                        fosh_add(owner_id, line)
                        added += 1
        except Exception as e:
            await event.edit(f"⚠خطا در خواندن فایل: {e}")
            return

        await event.edit(f"●{added}متن فایل به فوش ها اضاف شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
#==================== هندلر لیست اتکر ====================

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک add (.+)$'))
    async def atker_add(event):
        username = event.pattern_match.group(1).strip()

        if not username.startswith("@"):
            await event.edit("یوزرنیم باید با @ شروع بشه!")
            return

        try:
            e = await client.get_entity(username)
            atker_add_mention(event.chat_id, e.id, e.username or str(e.id))
            await event.edit(f"●کاربر{username}به اتکر اضاف شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
        except:
            await event.edit("کاربر پیدا نشد!")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک del (.+)$'))
    async def atker_del(event):
        username = event.pattern_match.group(1).strip()

        if not username.startswith("@"):
            await event.edit("یوزرنیم باید با @ شروع بشه!")
            return

        try:
            e = await client.get_entity(username)
            atker_remove_mention(event.chat_id, e.id)
            await event.edit(f"●کاربر{username}حذف شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
        except:                                                                             await event.edit("⚠️ کاربر پیدا نشد!")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک list$'))
    async def atker_list(event):
        mentions = atker_get_mentions(event.chat_id)

        if not mentions:
            await event.edit("لیست اتکر خالیه!")
            return

        msg = "لیست اتکر:\n"
        for uid, uname in mentions:
            msg += f"• {uname or uid}\n"

        await event.edit(msg)

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک clean$'))
    async def atker_clean(event):
        atker_clear_mentions(event.chat_id)
        await event.edit("●لیست اتکر خالیشد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
#==================== تسک اصلی اتکر ====================

    atker_tasks = {}

    async def atker_task(chat_id, owner_id):
        while True:
            if atker_get("atker_active") != "ON":
                break

            mentions = atker_get_mentions(chat_id)
            if not mentions:
                await asyncio.sleep(2)
                continue

            timer = float(atker_get("atker_timer", "5"))
            symbol = atker_get("atker_symbol", "𒆙")

            for uid, uname in mentions:
                if atker_get("atker_active") != "ON":
                    break

                fosh = fosh_random(owner_id)
                msg = f"{fosh}\n\n[{symbol}](tg://user?id={uid})"

                await client.send_message(chat_id, msg, parse_mode="md")
                await asyncio.sleep(timer)
#==================== کنترل اتکر ====================

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک start$'))
    async def atker_start(event):
        chat = event.chat_id
        owner = event.sender_id

        if not atker_get_mentions(chat):
            await event.edit("لیست اتکر خالیه")
            return

        if atker_get("atker_active") == "ON":
            await event.edit("اتکر همین الان فعاله!")
            return

        atker_set("atker_active", "ON")
        atker_tasks[chat] = asyncio.create_task(atker_task(chat, owner))
        await event.edit("●اتکر شروع شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک stop$'))
    async def atker_stop(event):
        chat = event.chat_id

        atker_set("atker_active", "OFF")

        if chat in atker_tasks:
            try:
                atker_tasks[chat].cancel()
            except:
                pass
            del atker_tasks[chat]

        await event.edit("●اتکر خاموش شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک timer (.+)$'))
    async def atker_timer(event):
        try:                                                                                t = float(event.pattern_match.group(1).strip())
            atker_set("atker_timer", str(t))
            await event.edit(f"●تایمر روی{t}ثانیه تنظیم شد♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")
        except:
            await event.edit("⚠️ عدد معتبر نیست!")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.اتک emoji (.+)$'))
    async def atker_emoji(event):
        emoji = event.pattern_match.group(1).strip()
        atker_set("atker_symbol", emoji)
        await event.edit(f"●ایموجی به{emoji}تغییر یافت♕𝙎𝙀𝙇𝙁 𝙑𝙞𝙙𝙖𝙡●")


#========= اجرای دائمی =========