
import json
import os
import asyncio
import sqlite3
import re
import random
import time
import smtplib
import email.utils
from email.mime.text import MIMEText
from datetime import datetime
from typing import List, Dict, Any, Optional
from telethon import TelegramClient, errors
from telethon.tl.functions.messages import ReportRequest
from telethon.tl.functions.account import ReportPeerRequest
from telethon.tl.functions.contacts import BlockRequest
from telethon.tl.types import (
    InputReportReasonSpam,
    InputReportReasonViolence,
    InputReportReasonPornography,
    InputReportReasonChildAbuse,
    InputReportReasonCopyright,
    InputReportReasonIllegalDrugs,
    InputReportReasonPersonalDetails,
    InputReportReasonFake,
)
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
    Application, CommandHandler, CallbackQueryHandler,
    MessageHandler, filters, ConversationHandler, ContextTypes
)
if not os.path.exists('config.json'):
    config = {
        "bot_token": "YOUR_BOT_TOKEN_HERE",
        "admin_ids": []
    }
    with open('config.json', 'w') as f:
        json.dump(config, f, indent=2)
    print("❌ Please edit config.json with your bot token and admin IDs")
    exit()
with open('config.json', 'r') as f:
    CONFIG = json.load(f)
BOT_TOKEN = CONFIG['bot_token']
ADMIN_IDS = set(CONFIG.get('admin_ids', []))
ADD_API_ID, ADD_API_HASH, ADD_PHONE, ADD_CODE, ADD_2FA = range(1, 6)
SEND_TARGET, SEND_MSG, SEND_COUNT = range(10, 13)
REPORT_TARGET = 20
REPORT_CATEGORY, REPORT_SUBCATEGORY, REPORT_COMMENT, REPORT_COUNT = range(30, 34)
REPORT_MULTI_USERS = 35
REPORT_STORY = 36
REPORT_MULTI_MESSAGE = 37
BLOCK_TARGET = 40
BULK_TARGETS = 60
MONITOR_TARGET = 70
MONITOR_INTERVAL = 71
ADD_EMAIL, ADD_EMAIL_PASSWORD, ADD_EMAIL_BULK = range(100, 103)
EMAIL_REPORT_TARGETS = 110
EMAIL_REPORT_CATEGORY = 111
EMAIL_REPORT_CONFIRM = 112
EMAIL_REPORT_COUNT = 113
EMAIL_REPORT_RECIPIENTS = [
    "abuse@telegram.org",
    "support@telegram.org",
    "stopCA@telegram.org",
    "dmca@telegram.org"
]
EMAIL_TEMPLATES = {
    "spam": {
        "subject": "Report: Spam / Unsolicited Messages",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is engaging in spam activities on Telegram.
Target: {target}
Category: Spam
Description:
The reported account has been sending unsolicited bulk messages, promotional content, or repetitive spam.
Please investigate and take appropriate action against this violator.
Thank you for your attention.
Regards,
Telegram User
"""
    },
    "violence": {
        "subject": "URGENT: Violence / Threats Report",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is promoting or threatening violence on Telegram.
Target: {target}
Category: Violence / Threats
Description:
The reported account contains content that incites violence, makes threats, or promotes harm against individuals or groups.
This is a serious violation of Telegram's terms of service.
Please investigate and take immediate action.
Thank you.
Regards,
Telegram User
"""
    },
    "child_abuse": {
        "subject": "URGENT: Child Abuse Content Report",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that contains child abuse material or exploitation content.
Target: {target}
Category: Child Abuse / Exploitation
Description:
The reported account contains content that violates Telegram's policy regarding child safety.
This requires immediate attention and action.
Thank you for your prompt response.
Regards,
Telegram User
"""
    },
    "illegal_goods": {
        "subject": "Report: Illegal Goods / Services",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is promoting or selling illegal goods/services.
Target: {target}
Category: Illegal Drugs / Weapons / Counterfeit
Description:
The reported account is involved in the sale or promotion of illegal items, including drugs, weapons, or stolen data.
Please investigate and remove this content.
Thank you.
Regards,
Telegram User
"""
    },
    "adult_content": {
        "subject": "Report: Adult / Pornographic Content",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that contains adult or pornographic content without proper restriction.
Target: {target}
Category: Adult Content / Pornography
Description:
The reported account shares explicit adult content that may violate Telegram's content policies.
Please review and take appropriate action.
Thank you.
Regards,
Telegram User
"""
    },
    "personal_data": {
        "subject": "Report: Personal Data / Doxxing",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is sharing personal/private information without consent.
Target: {target}
Category: Personal Data / Doxxing
Description:
The reported account has shared private information including phone numbers, addresses, or other personal data.
Please remove this content and take action against the violator.
Thank you.
Regards,
Telegram User
"""
    },
    "scam_fraud": {
        "subject": "Report: Scam / Fraud / Impersonation",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is involved in scam or fraudulent activities.
Target: {target}
Category: Scam / Fraud / Impersonation
Description:
The reported account is impersonating someone else, running a fake investment scheme, or conducting phishing activities.
Please investigate and take appropriate legal action.
Thank you.
Regards,
Telegram User
"""
    },
    "copyright": {
        "subject": "DMCA / Copyright Infringement Report",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is infringing on copyright.
Target: {target}
Category: Copyright Infringement
Description:
The reported account is sharing copyrighted content without permission from the rights holder.
Please remove the infringing content in accordance with DMCA and your copyright policy.
Thank you for your cooperation.
Regards,
Telegram User
"""
    },
    "other": {
        "subject": "Report: Terms of Service Violation",
        "body": """Dear Telegram Support Team,
I am reporting a user/channel that is violating Telegram's Terms of Service.
Target: {target}
Category: Other Violation
Description:
The reported account is engaged in activities that violate Telegram's community guidelines.
Please investigate and take appropriate action.
Thank you.
Regards,
Telegram User
"""
    }
}
def init_db():
    conn = sqlite3.connect('reporter.db')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS accounts (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            api_id INTEGER NOT NULL,
            api_hash TEXT NOT NULL,
            phone TEXT UNIQUE NOT NULL,
            added_date TEXT DEFAULT CURRENT_TIMESTAMP,
            is_enabled INTEGER DEFAULT 1,
            is_banned INTEGER DEFAULT 0,
            last_check TEXT,
            report_count INTEGER DEFAULT 0,
            success_count INTEGER DEFAULT 0,
            proxy TEXT
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS email_accounts (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email TEXT UNIQUE NOT NULL,
            password TEXT NOT NULL,
            added_date TEXT DEFAULT CURRENT_TIMESTAMP,
            is_enabled INTEGER DEFAULT 1,
            is_valid INTEGER DEFAULT 1,
            last_check TEXT,
            send_count INTEGER DEFAULT 0,
            success_count INTEGER DEFAULT 0
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS email_report_logs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email_account_id INTEGER,
            recipient TEXT,
            target TEXT,
            category TEXT,
            subject TEXT,
            body TEXT,
            status TEXT,
            timestamp TEXT DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS report_logs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            account_id INTEGER,
            target TEXT,
            target_name TEXT,
            target_id INTEGER,
            category TEXT,
            subcategory TEXT,
            comment TEXT,
            report_count INTEGER DEFAULT 1,
            is_story INTEGER DEFAULT 0,
            status TEXT,
            attack_start TEXT,
            attack_end TEXT,
            duration_seconds INTEGER,
            timestamp TEXT DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS monitoring (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            target_username TEXT,
            target_id TEXT,
            added_date TEXT DEFAULT CURRENT_TIMESTAMP,
            last_status TEXT,
            last_check TEXT,
            is_active INTEGER DEFAULT 1,
            notified_banned INTEGER DEFAULT 0
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS monitoring_logs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            target_id TEXT,
            target_username TEXT,
            status TEXT,
            check_time TEXT
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS stats (
            key TEXT PRIMARY KEY,
            value INTEGER DEFAULT 0
        )
    ''')

    conn.execute('''
        CREATE TABLE IF NOT EXISTS settings (
            key TEXT PRIMARY KEY,
            value TEXT
        )
    ''')

    conn.commit()
    conn.close()

    conn = sqlite3.connect('reporter.db')
    conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('monitor_interval', '5')")
    conn.commit()
    conn.close()
init_db()
def add_email_account(email, password):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "INSERT OR REPLACE INTO email_accounts (email, password, is_enabled, is_valid) VALUES (?, ?, 1, 1)",
        (email, password)
    )
    conn.commit()
    conn.close()
def get_all_email_accounts():
    conn = sqlite3.connect('reporter.db')
    accounts = conn.execute(
        "SELECT id, email, is_enabled, is_valid, send_count, success_count FROM email_accounts"
    ).fetchall()
    conn.close()
    return accounts
def get_enabled_email_accounts():
    conn = sqlite3.connect('reporter.db')
    accounts = conn.execute(
        "SELECT id, email, password FROM email_accounts WHERE is_enabled = 1 AND is_valid = 1"
    ).fetchall()
    conn.close()
    return accounts
def toggle_email_account_enabled(account_id):
    conn = sqlite3.connect('reporter.db')
    current = conn.execute("SELECT is_enabled FROM email_accounts WHERE id = ?", (account_id,)).fetchone()
    if current:
        new_status = 0 if current[0] else 1
        conn.execute("UPDATE email_accounts SET is_enabled = ? WHERE id = ?", (new_status, account_id))
        conn.commit()
        conn.close()
        return bool(new_status)
    conn.close()
    return False
def delete_email_account(account_id):
    conn = sqlite3.connect('reporter.db')
    conn.execute("DELETE FROM email_accounts WHERE id = ?", (account_id,))
    conn.commit()
    conn.close()
def update_email_account_stats(account_id, success=True):
    conn = sqlite3.connect('reporter.db')
    if success:
        conn.execute("UPDATE email_accounts SET send_count = send_count + 1, success_count = success_count + 1 WHERE id = ?", (account_id,))
    else:
        conn.execute("UPDATE email_accounts SET send_count = send_count + 1 WHERE id = ?", (account_id,))
    conn.commit()
    conn.close()
def update_email_account_valid(account_id, is_valid=True):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE email_accounts SET is_valid = ?, last_check = ? WHERE id = ?",
                 (1 if is_valid else 0, datetime.now().isoformat(), account_id))
    conn.commit()
    conn.close()
def add_email_report_log(email_account_id, recipient, target, category, subject, body, status):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "INSERT INTO email_report_logs (email_account_id, recipient, target, category, subject, body, status) VALUES (?, ?, ?, ?, ?, ?, ?)",
        (email_account_id, recipient, target, category, subject, body, status)
    )
    conn.commit()
    conn.close()
async def test_email_connection(email, password):
    """Test if email credentials work (async version)"""
    try:
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(
            None,
            _smtp_test_connection,
            email,
            password
        )
        return result
    except Exception as e:
        return False, str(e)
def _smtp_test_connection(email, password):
    """Synchronous SMTP test function"""
    try:
        server = smtplib.SMTP('smtp.gmail.com', 587, timeout=15)
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(email, password)
        server.quit()
        return True, "Connection successful"
    except smtplib.SMTPAuthenticationError as e:
        return False, f"Authentication failed: Check email/App Password. {str(e)}"
    except smtplib.SMTPServerDisconnected as e:
        return False, f"Server disconnected: {str(e)}"
    except smtplib.SMTPException as e:
        return False, f"SMTP error: {str(e)}"
    except Exception as e:
        return False, str(e)
async def send_email_via_smtp(sender_email, sender_password, recipient, subject, body):
    """Send email via Gmail SMTP (async version)"""
    try:
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(
            None,
            _smtp_send_email,
            sender_email,
            sender_password,
            recipient,
            subject,
            body
        )
        return result
    except Exception as e:
        return False, str(e)
def _smtp_send_email(sender_email, sender_password, recipient, subject, body):
    """Synchronous email sending function"""
    try:
        msg = MIMEText(body, 'plain', 'utf-8')
        msg['Subject'] = subject
        msg['From'] = sender_email
        msg['To'] = recipient
        msg['Date'] = email.utils.formatdate(localtime=True)

        server = smtplib.SMTP('smtp.gmail.com', 587, timeout=30)
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(sender_email, sender_password)
        server.send_message(msg)
        server.quit()

        return True, "Email sent successfully"
    except smtplib.SMTPAuthenticationError as e:
        return False, f"Authentication failed: {str(e)}"
    except Exception as e:
        return False, str(e)
def add_account(api_id, api_hash, phone, proxy=None):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "INSERT OR REPLACE INTO accounts (api_id, api_hash, phone, proxy, is_enabled) VALUES (?, ?, ?, ?, 1)",
        (api_id, api_hash, phone, proxy)
    )
    conn.commit()
    conn.close()
def get_all_accounts():
    conn = sqlite3.connect('reporter.db')
    accounts = conn.execute(
        "SELECT id, api_id, api_hash, phone, proxy, is_enabled, is_banned, report_count, success_count FROM accounts"
    ).fetchall()
    conn.close()
    return accounts
def get_enabled_accounts():
    conn = sqlite3.connect('reporter.db')
    accounts = conn.execute(
        "SELECT id, api_id, api_hash, phone, proxy FROM accounts WHERE is_enabled = 1 AND is_banned = 0"
    ).fetchall()
    conn.close()
    return accounts
def get_account_by_id(account_id):
    conn = sqlite3.connect('reporter.db')
    acc = conn.execute(
        "SELECT id, api_id, api_hash, phone, proxy, is_enabled FROM accounts WHERE id = ?",
        (account_id,)
    ).fetchone()
    conn.close()
    return acc
def toggle_account_enabled(account_id):
    conn = sqlite3.connect('reporter.db')
    current = conn.execute("SELECT is_enabled FROM accounts WHERE id = ?", (account_id,)).fetchone()
    if current:
        new_status = 0 if current[0] else 1
        conn.execute("UPDATE accounts SET is_enabled = ? WHERE id = ?", (new_status, account_id))
        conn.commit()
        conn.close()
        return bool(new_status)
    conn.close()
    return False
def delete_account(account_id):
    conn = sqlite3.connect('reporter.db')
    phone = conn.execute("SELECT phone FROM accounts WHERE id = ?", (account_id,)).fetchone()
    if phone:
        session_file = f"sessions/{phone[0]}.session"
        if os.path.exists(session_file):
            os.remove(session_file)
    conn.execute("DELETE FROM accounts WHERE id = ?", (account_id,))
    conn.commit()
    conn.close()
def update_account_stats(account_id, success=True):
    conn = sqlite3.connect('reporter.db')
    if success:
        conn.execute("UPDATE accounts SET report_count = report_count + 1, success_count = success_count + 1 WHERE id = ?", (account_id,))
    else:
        conn.execute("UPDATE accounts SET report_count = report_count + 1 WHERE id = ?", (account_id,))
    conn.commit()
    conn.close()
def update_account_banned(account_id, is_banned=True):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE accounts SET is_banned = ?, last_check = ? WHERE id = ?",
                 (1 if is_banned else 0, datetime.now().isoformat(), account_id))
    conn.commit()
    conn.close()
def update_account_last_check(account_id):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE accounts SET last_check = ? WHERE id = ?",
                 (datetime.now().isoformat(), account_id))
    conn.commit()
    conn.close()
def update_account_proxy(account_id, proxy):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE accounts SET proxy = ? WHERE id = ?", (proxy, account_id))
    conn.commit()
    conn.close()
def add_report_log(account_id, target, target_name, target_id, category, subcategory, comment, report_count, is_story, status, duration_seconds):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "INSERT INTO report_logs (account_id, target, target_name, target_id, category, subcategory, comment, report_count, is_story, status, attack_start, attack_end, duration_seconds) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
        (account_id, target, target_name, target_id, category, subcategory, comment, report_count, is_story, status,
         datetime.now().isoformat(), datetime.now().isoformat(), duration_seconds)
    )
    conn.execute("UPDATE stats SET value = value + ? WHERE key = 'total_reports'", (report_count,))
    conn.commit()
    conn.close()
def get_stats():
    conn = sqlite3.connect('reporter.db')
    total = conn.execute("SELECT COUNT(*) FROM accounts WHERE is_banned = 0").fetchone()[0]
    enabled = conn.execute("SELECT COUNT(*) FROM accounts WHERE is_enabled = 1 AND is_banned = 0").fetchone()[0]
    reports = conn.execute("SELECT value FROM stats WHERE key = 'total_reports'").fetchone()
    total_reports = reports[0] if reports else 0

    email_total = conn.execute("SELECT COUNT(*) FROM email_accounts").fetchone()[0]
    email_enabled = conn.execute("SELECT COUNT(*) FROM email_accounts WHERE is_enabled = 1 AND is_valid = 1").fetchone()[0]
    email_sent = conn.execute("SELECT SUM(send_count) FROM email_accounts").fetchone()[0] or 0

    conn.close()
    return total, enabled, total_reports, email_total, email_enabled, email_sent
async def check_telegram_account_status(account_id, api_id, api_hash, phone, proxy_str):
    """Check if a Telegram account is active/banned"""
    proxy = None
    if proxy_str:
        proxy_dict = parse_proxy_string(proxy_str)
        if proxy_dict:
            proxy = proxy_dict

    try:
        client = TelegramClient(f"sessions/{phone}", api_id, api_hash, proxy=proxy)
        await client.connect()

        if not await client.is_user_authorized():
            await client.disconnect()
            return {"status": "not_authorized", "message": "Not logged in"}

        me = await client.get_me()
        await client.disconnect()
        return {"status": "active", "message": f"@{me.username}" if me.username else me.first_name}
    except errors.FloodWaitError as e:
        return {"status": "flood_wait", "message": f"Flood wait {e.seconds}s"}
    except Exception as e:
        error_str = str(e).lower()
        if 'banned' in error_str or 'deactivated' in error_str:
            update_account_banned(account_id, True)
            return {"status": "banned", "message": "Account banned"}
        return {"status": "error", "message": str(e)[:50]}
async def check_all_telegram_accounts():
    """Check status of all Telegram accounts"""
    accounts = get_all_accounts()
    results = []

    for acc in accounts:
        acc_id, api_id, api_hash, phone, proxy, is_enabled, is_banned, rep, suc = acc
        if is_banned:
            results.append({"phone": phone, "status": "banned", "message": "Previously banned"})
            continue

        status = await check_telegram_account_status(acc_id, api_id, api_hash, phone, proxy)
        results.append({"phone": phone, "status": status["status"], "message": status["message"]})
        await asyncio.sleep(1)

    return results
def check_all_email_accounts():
    """Check status of all email accounts"""
    accounts = get_all_email_accounts()
    results = []

    for acc in accounts:
        acc_id, email, is_enabled, is_valid, send_count, success_count = acc
        if not is_enabled:
            results.append({"email": email, "status": "disabled", "message": "Manually disabled"})
            continue
        if not is_valid:
            results.append({"email": email, "status": "invalid", "message": "Previously invalid"})
            continue

        conn = sqlite3.connect('reporter.db')
        pass_row = conn.execute("SELECT password FROM email_accounts WHERE id = ?", (acc_id,)).fetchone()
        conn.close()
        password = pass_row[0] if pass_row else None

        if not password:
            results.append({"email": email, "status": "error", "message": "No password"})
            continue

        success, msg = test_email_connection(email, password)
        if success:
            update_email_account_valid(acc_id, True)
            results.append({"email": email, "status": "valid", "message": "Connected"})
        else:
            update_email_account_valid(acc_id, False)
            results.append({"email": email, "status": "invalid", "message": msg[:50]})

    return results
def add_to_monitoring(target_username, target_id):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "INSERT OR REPLACE INTO monitoring (target_username, target_id, is_active, notified_banned) VALUES (?, ?, 1, 0)",
        (target_username, target_id)
    )
    conn.commit()
    conn.close()
def remove_from_monitoring(target_id):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE monitoring SET is_active = 0 WHERE target_id = ?", (target_id,))
    conn.commit()
    conn.close()
def get_monitored_targets():
    conn = sqlite3.connect('reporter.db')
    targets = conn.execute(
        "SELECT id, target_username, target_id, last_status, last_check, is_active FROM monitoring WHERE is_active = 1"
    ).fetchall()
    conn.close()
    return targets
def update_monitoring_status(target_id, status):
    conn = sqlite3.connect('reporter.db')
    conn.execute(
        "UPDATE monitoring SET last_status = ?, last_check = ? WHERE target_id = ?",
        (status, datetime.now().isoformat(), target_id)
    )
    conn.execute(
        "INSERT INTO monitoring_logs (target_id, target_username, status, check_time) SELECT target_id, target_username, ?, ? FROM monitoring WHERE target_id = ?",
        (status, datetime.now().isoformat(), target_id)
    )
    conn.commit()
    conn.close()
def is_target_banned_notified(target_id):
    conn = sqlite3.connect('reporter.db')
    result = conn.execute("SELECT notified_banned FROM monitoring WHERE target_id = ?", (target_id,)).fetchone()
    conn.close()
    return result[0] if result else 0
def set_target_notified(target_id, notified=True):
    conn = sqlite3.connect('reporter.db')
    conn.execute("UPDATE monitoring SET notified_banned = ? WHERE target_id = ?", (1 if notified else 0, target_id))
    conn.commit()
    conn.close()
def get_monitor_interval():
    conn = sqlite3.connect('reporter.db')
    result = conn.execute("SELECT value FROM settings WHERE key = 'monitor_interval'").fetchone()
    conn.close()
    return int(result[0]) if result else 5
def set_monitor_interval(minutes):
    conn = sqlite3.connect('reporter.db')
    conn.execute("INSERT OR REPLACE INTO settings (key, value) VALUES ('monitor_interval', ?)", (str(minutes),))
    conn.commit()
    conn.close()
def parse_proxy_string(proxy_str):
    """Parse proxy string like socks5://user:pass@host:port"""
    if not proxy_str or proxy_str.lower() == 'none':
        return None

    import re
    pattern = r'^(socks5|socks4|http)://(?:([^:]+):([^@]+)@)?([^:]+):(\d+)$'
    match = re.match(pattern, proxy_str)

    if match:
        proxy_type, username, password, host, port = match.groups()
        proxy_dict = {
            'proxy_type': proxy_type,
            'addr': host,
            'port': int(port)
        }
        if username and password:
            proxy_dict['username'] = username
            proxy_dict['password'] = password
        return proxy_dict
    return None
LEVEL_1_CATEGORIES = {
    "spam": "📢 Spam",
    "violence": "🔫 Violence",
    "child_abuse": "👶 Child Abuse",
    "illegal_goods": "💊 Illegal goods",
    "adult_content": "🔞 Adult content",
    "personal_data": "🆔 Personal data",
    "scam_fraud": "🎭 Scam/Fraud",
    "copyright": "📜 Copyright",
    "other": "❓ Other"
}
LEVEL_2_SUBCATEGORIES = {
    "spam": ["Promoting others", "Irrelevant content", "Misleading", "Excessive posting", "Unsolicited messages", "Bot spam"],
    "violence": ["Graphic violence", "Threats", "Terrorism", "Animal abuse", "Harassment", "Self-harm"],
    "child_abuse": ["Exploitation", "Abusive content", "Solicitation", "Grooming"],
    "illegal_goods": ["Drugs", "Weapons", "Counterfeit", "Stolen data", "Hacking", "Terrorism materials"],
    "adult_content": ["Non-consensual", "Extreme content", "Underage", "Pornography"],
    "personal_data": ["Doxxing", "Private photos", "Location sharing", "Identity theft"],
    "scam_fraud": ["Impersonation", "Fake channel", "Phishing", "Investment scam", "Fake profile", "Romance scam"],
    "copyright": ["Copyrighted content", "Trademark", "Counterfeit goods"],
    "other": ["Other reason", "Not specified"]
}
REQUIRE_COMMENT = ["personal_data", "copyright", "other"]
REPORT_REASONS_MAP = {
    "spam": InputReportReasonSpam(),
    "violence": InputReportReasonViolence(),
    "adult_content": InputReportReasonPornography(),
    "child_abuse": InputReportReasonChildAbuse(),
    "copyright": InputReportReasonCopyright(),
    "illegal_goods": InputReportReasonIllegalDrugs(),
    "personal_data": InputReportReasonPersonalDetails(),
    "scam_fraud": InputReportReasonFake(),
}
def extract_from_link(text: str):
    patterns = [
        r'https?://t\.me/([^/]+)/(\d+)',
        r'https?://telegram\.me/([^/]+)/(\d+)',
        r't\.me/([^/]+)/(\d+)'
    ]
    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            return match.group(1), int(match.group(2))
    return None, None
def extract_chat_from_link(text: str):
    patterns = [
        r'https?://t\.me/([^/\s]+)',
        r'https?://telegram\.me/([^/\s]+)',
        r't\.me/([^/\s]+)'
    ]
    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            username = match.group(1)
            if username not in ['joinchat', '+']:
                return username
    return None
def extract_usernames_from_text(text: str):
    usernames = []
    lines = text.split('\n')
    for line in lines:
        line = line.strip()
        if not line:
            continue

        username, _ = extract_from_link(line)
        if username:
            usernames.append(username)
            continue

        username = extract_chat_from_link(line)
        if username:
            usernames.append(username)
            continue

        if line.startswith('@'):
            usernames.append(line[1:])
        elif line.lstrip('-').isdigit():
            usernames.append(line)
        else:
            usernames.append(line)

    return list(dict.fromkeys(usernames))
async def check_target_exists(client, target):
    try:
        target = target.strip().lstrip('@')
        if target.lstrip('-').isdigit():
            entity = await client.get_entity(int(target))
        else:
            entity = await client.get_entity(target)

        info = {
            'exists': True,
            'id': entity.id,
            'type': 'unknown'
        }

        if hasattr(entity, 'first_name'):
            info['type'] = 'user' if not getattr(entity, 'bot', False) else 'bot'
            info['name'] = f"{entity.first_name} {getattr(entity, 'last_name', '')}".strip()
            info['username'] = f"@{entity.username}" if hasattr(entity, 'username') and entity.username else None
        elif hasattr(entity, 'title'):
            info['type'] = 'channel' if getattr(entity, 'broadcast', False) else 'group'
            info['title'] = entity.title
            info['username'] = f"@{entity.username}" if hasattr(entity, 'username') and entity.username else None

        return info
    except errors.FloodWaitError as e:
        return {'exists': False, 'error': f'Flood wait {e.seconds}s'}
    except errors.UserDeactivatedError:
        return {'exists': False, 'error': 'User deactivated'}
    except errors.UserBannedError:
        return {'exists': False, 'error': 'User banned'}
    except errors.PeerFloodError:
        return {'exists': False, 'error': 'You have been limited'}
    except Exception as e:
        error_str = str(e).lower()
        if 'not found' in error_str or 'invalid' in error_str:
            return {'exists': False, 'error': 'Target not found'}
        return {'exists': False, 'error': str(e)[:50]}
def format_duration(seconds):
    if seconds < 60:
        return f"{seconds} seconds"
    elif seconds < 3600:
        minutes = seconds // 60
        secs = seconds % 60
        return f"{minutes} min {secs} sec"
    else:
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        return f"{hours} hr {minutes} min"
def get_home_button():
    return [InlineKeyboardButton("🏠 Back to Home", callback_data="main_menu", style="primary")]
def get_main_keyboard():
    keyboard = [
        [InlineKeyboardButton("📋 Account Manager", callback_data="menu_accounts", style="primary")],
        [InlineKeyboardButton("✉️ Send Message", callback_data="menu_send", style="primary")],
        [InlineKeyboardButton("🚨 Report", callback_data="menu_report", style="success")],
        [InlineKeyboardButton("🚫 Block User", callback_data="menu_block", style="danger")],
        [InlineKeyboardButton("📊 Bulk Report", callback_data="menu_bulk", style="success")],
        [InlineKeyboardButton("👥 Multi User Report", callback_data="menu_multi_user", style="success")],
        [InlineKeyboardButton("📖 Story Report", callback_data="menu_story", style="primary")],
        [InlineKeyboardButton("📝 Multi Message", callback_data="menu_multi_message", style="primary")],
        [InlineKeyboardButton("👁️ Monitoring", callback_data="menu_monitoring", style="primary")],
        [InlineKeyboardButton("📧 Email Report", callback_data="menu_email_report", style="success")],
        [InlineKeyboardButton("📊 Check All Status", callback_data="check_all_status", style="primary")],
        [InlineKeyboardButton("📈 Statistics", callback_data="menu_stats", style="primary")],
        [InlineKeyboardButton("📋 Report Logs", callback_data="menu_logs", style="primary")],
        [InlineKeyboardButton("⚙️ Settings", callback_data="menu_settings", style="primary")],
        [InlineKeyboardButton("❓ Help & Support", callback_data="menu_help", style="primary")]
    ]
    return InlineKeyboardMarkup(keyboard)
def get_email_main_keyboard():
    keyboard = [
        [InlineKeyboardButton("➕ Add Email Account", callback_data="add_email_account", style="success")],
        [InlineKeyboardButton("🔘 Toggle Email Accounts", callback_data="toggle_email_accounts", style="primary")],
        [InlineKeyboardButton("📧 Send Email Report", callback_data="start_email_report", style="success")],
        [InlineKeyboardButton("📋 Email Logs", callback_data="email_logs", style="primary")],
        [InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")]
    ]
    return InlineKeyboardMarkup(keyboard)
def get_email_accounts_keyboard(action="select", page=0):
    accounts = get_all_email_accounts()
    if not accounts:
        return None

    keyboard = []
    per_page = 5
    start = page * per_page
    end = min(start + per_page, len(accounts))

    for acc in accounts[start:end]:
        acc_id, email, is_enabled, is_valid, send_count, success_count = acc
        status_icon = "✅" if (is_enabled and is_valid) else "❌" if not is_enabled else "⚠️"
        keyboard.append([InlineKeyboardButton(f"{status_icon} {email}", callback_data=f"{action}_email_{acc_id}", style="success" if is_enabled else "danger")])

    nav = []
    if page > 0:
        nav.append(InlineKeyboardButton("◀️ Prev", callback_data=f"{action}_page_{page-1}", style="primary"))
    if end < len(accounts):
        nav.append(InlineKeyboardButton("Next ▶️", callback_data=f"{action}_page_{page+1}", style="primary"))
    if nav:
        keyboard.append(nav)

    keyboard.append([InlineKeyboardButton("⚡ ALL Enabled", callback_data=f"{action}_all", style="primary")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="menu_email_report", style="danger")])

    return InlineKeyboardMarkup(keyboard)
def get_toggle_email_keyboard(page=0):
    accounts = get_all_email_accounts()
    if not accounts:
        return None

    keyboard = []
    per_page = 5
    start = page * per_page
    end = min(start + per_page, len(accounts))

    for acc in accounts[start:end]:
        acc_id, email, is_enabled, is_valid, send_count, success_count = acc
        if is_enabled and is_valid:
            icon = "✅"
        elif not is_enabled:
            icon = "❌"
        else:
            icon = "⚠️"

        keyboard.append([InlineKeyboardButton(f"{icon} {email} | 📊:{send_count} | ✅:{success_count}", callback_data=f"toggle_email_{acc_id}", style="success" if is_enabled else "danger")])

    nav = []
    if page > 0:
        nav.append(InlineKeyboardButton("◀️ Prev", callback_data=f"toggle_email_page_{page-1}", style="primary"))
    if end < len(accounts):
        nav.append(InlineKeyboardButton("Next ▶️", callback_data=f"toggle_email_page_{page+1}", style="primary"))
    if nav:
        keyboard.append(nav)

    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="menu_email_report", style="danger")])

    return InlineKeyboardMarkup(keyboard)
def get_email_categories_keyboard():
    keyboard = []
    for key, label in LEVEL_1_CATEGORIES.items():
        keyboard.append([InlineKeyboardButton(label, callback_data=f"email_cat_{key}", style="primary")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="menu_email_report", style="danger")])
    return InlineKeyboardMarkup(keyboard)
def get_email_confirm_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("✅ YES, Send Report", callback_data="email_confirm_yes", style="success")],
        [InlineKeyboardButton("✏️ Change Template", callback_data="email_confirm_edit", style="primary")],
        [InlineKeyboardButton("❌ Cancel", callback_data="email_confirm_no", style="danger")]
    ])
def get_email_template_choice_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("📝 Use Default Template", callback_data="email_template_default", style="success")],
        [InlineKeyboardButton("✏️ Write Custom Message", callback_data="email_template_custom", style="primary")]
    ])
def get_email_recipients_keyboard():
    keyboard = []
    for recipient in EMAIL_REPORT_RECIPIENTS:
        keyboard.append([InlineKeyboardButton(f"📧 {recipient}", callback_data=f"email_recipient_{recipient}", style="primary")])
    keyboard.append([InlineKeyboardButton("📬 ALL Recipients", callback_data="email_recipient_all", style="success")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="menu_email_report", style="danger")])
    return InlineKeyboardMarkup(keyboard)
def get_accounts_keyboard(action="select", page=0):
    accounts = get_enabled_accounts()
    if not accounts:
        return None

    keyboard = []
    per_page = 5
    start = page * per_page
    end = min(start + per_page, len(accounts))

    for acc in accounts[start:end]:
        acc_id, api_id, api_hash, phone, proxy = acc
        proxy_icon = "🔒" if proxy else ""
        keyboard.append([InlineKeyboardButton(f"✅ {phone} {proxy_icon}", callback_data=f"{action}_acc_{acc_id}", style="success")])

    nav = []
    if page > 0:
        nav.append(InlineKeyboardButton("◀️ Prev", callback_data=f"{action}_page_{page-1}", style="primary"))
    if end < len(accounts):
        nav.append(InlineKeyboardButton("Next ▶️", callback_data=f"{action}_page_{page+1}", style="primary"))
    if nav:
        keyboard.append(nav)

    keyboard.append([InlineKeyboardButton("⚡ ALL Enabled", callback_data=f"{action}_all", style="primary")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")])

    return InlineKeyboardMarkup(keyboard)
def get_toggle_accounts_keyboard(page=0):
    accounts = get_all_accounts()
    if not accounts:
        return None

    keyboard = []
    per_page = 4
    start = page * per_page
    end = min(start + per_page, len(accounts))

    for acc in accounts[start:end]:
        acc_id, api_id, api_hash, phone, proxy, is_enabled, is_banned, rep, suc = acc

        if is_banned:
            status_icon = "🚫"
            btn_style = "danger"
        elif is_enabled:
            session_exists = os.path.exists(f"sessions/{phone}.session")
            status_icon = "✅" if session_exists else "⚠️"
            btn_style = "success" if session_exists else "primary"
        else:
            status_icon = "❌"
            btn_style = "danger"

        proxy_icon = " 🔒" if proxy else ""

        keyboard.append([InlineKeyboardButton(
            f"{status_icon} {phone}{proxy_icon} | 📊:{rep} | ✅:{suc}",
            callback_data=f"toggle_acc_{acc_id}",
            style=btn_style
        )])

    nav = []
    if page > 0:
        nav.append(InlineKeyboardButton("◀️ Prev", callback_data=f"toggle_page_{page-1}", style="primary"))
    if end < len(accounts):
        nav.append(InlineKeyboardButton("Next ▶️", callback_data=f"toggle_page_{page+1}", style="primary"))
    if nav:
        keyboard.append(nav)

    keyboard.append([InlineKeyboardButton("💾 SAVE & NEXT", callback_data="save_and_next", style="success")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")])

    return InlineKeyboardMarkup(keyboard)
def get_level_1_keyboard():
    keyboard = []
    for key, label in LEVEL_1_CATEGORIES.items():
        style = "danger" if key in ["child_abuse", "violence"] else "primary"
        keyboard.append([InlineKeyboardButton(label, callback_data=f"cat_{key}", style=style)])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")])
    return InlineKeyboardMarkup(keyboard)
def get_level_2_keyboard(category):
    subcats = LEVEL_2_SUBCATEGORIES.get(category, ["Other"])
    keyboard = []
    for sub in subcats:
        keyboard.append([InlineKeyboardButton(f"├ {sub}", callback_data=f"sub_{category}_{sub}", style="primary")])
    keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="back_categories", style="danger")])
    return InlineKeyboardMarkup(keyboard)
def get_comment_choice_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("✅ Yes, add comment", callback_data="comment_yes", style="success")],
        [InlineKeyboardButton("⏭️ No, skip comment", callback_data="comment_no", style="primary")]
    ])
def get_proxy_choice_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("✅ Yes, add proxy", callback_data="proxy_yes", style="success")],
        [InlineKeyboardButton("⏭️ No, skip proxy", callback_data="proxy_no", style="primary")]
    ])
def get_confirmation_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("✅ YES, Start Report", callback_data="confirm_yes", style="success")],
        [InlineKeyboardButton("❌ NO, Cancel", callback_data="confirm_no", style="danger")],
        [InlineKeyboardButton("✏️ Change Reason", callback_data="confirm_change", style="primary")]
    ])
def get_monitoring_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("➕ Add to Monitoring", callback_data="monitor_add", style="success")],
        [InlineKeyboardButton("📋 List Monitored", callback_data="monitor_list", style="primary")],
        [InlineKeyboardButton("🗑️ Remove from Monitoring", callback_data="monitor_remove", style="danger")],
        [InlineKeyboardButton("🔄 Check Now", callback_data="monitor_check_now", style="primary")],
        [InlineKeyboardButton("⚙️ Set Interval", callback_data="monitor_interval", style="primary")],
        [InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")],
        get_home_button()
    ])
def get_settings_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("📤 Export Accounts", callback_data="export_accounts", style="primary")],
        [InlineKeyboardButton("📥 Import Accounts", callback_data="import_accounts", style="primary")],
        [InlineKeyboardButton("🔒 Set Proxy", callback_data="set_proxy", style="primary")],
        [InlineKeyboardButton("🗑️ Clear Logs", callback_data="clear_logs", style="danger")],
        [InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="primary")],
        get_home_button()
    ])
def get_help_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("📖 How to Report", callback_data="help_report", style="primary")],
        [InlineKeyboardButton("📝 How to Send Message", callback_data="help_send", style="primary")],
        [InlineKeyboardButton("🚫 How to Block", callback_data="help_block", style="primary")],
        [InlineKeyboardButton("👥 Multi User Report", callback_data="help_multi", style="primary")],
        [InlineKeyboardButton("👁️ Monitoring System", callback_data="help_monitor", style="primary")],
        [InlineKeyboardButton("📧 Email Reporting", callback_data="help_email", style="primary")],
        [InlineKeyboardButton("🔒 Proxy Setup", callback_data="help_proxy", style="primary")],
        [InlineKeyboardButton("🆘 Support", callback_data="support", style="danger")],
        [InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="primary")],
        get_home_button()
    ])
async def get_client(account_id, quick_mode=False):
    acc = get_account_by_id(account_id)
    if not acc:
        return None
    acc_id, api_id, api_hash, phone, proxy_str, is_enabled = acc

    if not is_enabled:
        return None

    proxy = None
    if proxy_str and not quick_mode:
        proxy = parse_proxy_string(proxy_str)

    try:
        client = TelegramClient(f"sessions/{phone}", api_id, api_hash, proxy=proxy)
        await asyncio.wait_for(client.connect(), timeout=10)

        if not quick_mode and not await client.is_user_authorized():
            await client.disconnect()
            return None

        return client
    except asyncio.TimeoutError:
        return None
    except Exception:
        return None
async def resolve_target(client, target):
    target = target.strip().lstrip('@')
    if target.lstrip('-').isdigit():
        return await client.get_entity(int(target))
    return await client.get_entity(target)
async def send_report_action(client, peer, message_ids, category, comment="", is_story=False):
    try:
        reason_obj = REPORT_REASONS_MAP.get(category, InputReportReasonSpam())

        if is_story:
            await client(ReportPeerRequest(peer=peer, reason=reason_obj, message=comment))
        elif message_ids and message_ids != [0]:
            await client(ReportRequest(peer=peer, id=message_ids, reason=reason_obj, message=comment))
        else:
            await client(ReportPeerRequest(peer=peer, reason=reason_obj, message=comment))

        return {"success": True}
    except errors.FloodWaitError as e:
        return {"success": False, "error": f"⏳ Flood wait {e.seconds}s"}
    except Exception as e:
        return {"success": False, "error": str(e)[:100]}
async def check_account_status(client, account_id, phone):
    try:
        me = await client.get_me()
        if me:
            update_account_last_check(account_id)
            return {'is_banned': False, 'info': f"@{me.username}" if me.username else me.first_name}
    except errors.FloodWaitError as e:
        return {'is_banned': False, 'error': f'Flood wait {e.seconds}s'}
    except Exception as e:
        error_str = str(e).lower()
        if 'banned' in error_str or 'deactivated' in error_str:
            update_account_banned(account_id, True)
            return {'is_banned': True, 'error': 'Account banned'}
        return {'is_banned': False, 'error': str(e)[:50]}
async def execute_email_report(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    target = context.user_data.get('email_target')
    category = context.user_data.get('email_category')
    custom_body = context.user_data.get('email_custom_body')
    recipients = context.user_data.get('email_recipients', [])
    report_count = context.user_data.get('email_report_count', 2)
    account_id = context.user_data.get('email_account_id')
    use_all = context.user_data.get('email_all_accounts', False)

    if not target:
        await query.edit_message_text("❌ Target not found!", reply_markup=get_main_keyboard())
        return

    if use_all:
        accounts = get_enabled_email_accounts()
        account_ids = [a[0] for a in accounts]
    else:
        accounts = [get_enabled_email_accounts()[0]] if account_id else []
        account_ids = [account_id] if account_id else []

    if not account_ids:
        await query.edit_message_text("❌ No enabled email accounts!", reply_markup=get_main_keyboard())
        return

    if custom_body:
        email_body = custom_body
        subject = f"Report: {category} - {target}"
    else:
        template = EMAIL_TEMPLATES.get(category, EMAIL_TEMPLATES["other"])
        subject = template["subject"]
        email_body = template["body"].format(target=target)

    preview = f"<b>📧 EMAIL REPORT PREVIEW</b>\n\n"
    preview += f"🎯 Target: <code>{target}</code>\n"
    preview += f"📂 Category: {LEVEL_1_CATEGORIES.get(category, category)}\n"
    preview += f"📬 Recipients: {', '.join(recipients)}\n"
    preview += f"🔢 Count: {report_count} per account\n"
    preview += f"📧 Accounts: {len(account_ids)}\n\n"
    preview += f"<b>Subject:</b>\n<code>{subject[:100]}...</code>\n\n"
    preview += f"<b>Body:</b>\n<code>{email_body[:300]}...</code>\n\n"
    preview += f"<i>Send this report?</i>"

    context.user_data['email_subject'] = subject
    context.user_data['email_body'] = email_body
    context.user_data['email_recipients_final'] = recipients
    context.user_data['email_report_count_final'] = report_count
    context.user_data['email_account_ids'] = account_ids

    await query.edit_message_text(preview, reply_markup=get_email_confirm_keyboard(), parse_mode='HTML')
async def send_email_reports(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    account_ids = context.user_data.get('email_account_ids', [])
    recipients = context.user_data.get('email_recipients_final', [])
    subject = context.user_data.get('email_subject', '')
    body = context.user_data.get('email_body', '')
    target = context.user_data.get('email_target', '')
    category = context.user_data.get('email_category', 'other')
    report_count = context.user_data.get('email_report_count_final', 2)

    if not account_ids or not recipients:
        await query.edit_message_text("❌ Missing data!", reply_markup=get_main_keyboard())
        return

    await query.edit_message_text(
        f"<b>📧 SENDING EMAIL REPORTS</b>\n\n"
        f"🎯 Target: <code>{target}</code>\n"
        f"📬 Recipients: {len(recipients)}\n"
        f"📧 Accounts: {len(account_ids)}\n"
        f"🔢 Total emails: {len(account_ids) * len(recipients) * report_count}\n\n"
        f"⏳ Sending...",
        parse_mode='HTML'
    )

    total_sent = 0
    total_failed = 0

    for aid in account_ids:
        conn = sqlite3.connect('reporter.db')
        acc = conn.execute("SELECT email, password FROM email_accounts WHERE id = ?", (aid,)).fetchone()
        conn.close()

        if not acc:
            continue

        sender_email, sender_password = acc

        for recipient in recipients:
            for i in range(report_count):
                success, msg = await send_email_via_smtp(sender_email, sender_password, recipient, subject, body)

                if success:
                    total_sent += 1
                    update_email_account_stats(aid, True)
                    add_email_report_log(aid, recipient, target, category, subject, body, "success")
                else:
                    total_failed += 1
                    update_email_account_stats(aid, False)
                    add_email_report_log(aid, recipient, target, category, subject, body, f"failed: {msg[:50]}")

                await asyncio.sleep(random.uniform(5, 10))

        await asyncio.sleep(random.uniform(10, 20))

    summary = (
        f"<b>✅ EMAIL REPORT COMPLETED!</b>\n\n"
        f"🎯 Target: <code>{target}</code>\n"
        f"📂 Category: {LEVEL_1_CATEGORIES.get(category, category)}\n"
        f"✅ Sent: <b>{total_sent}</b>\n"
        f"❌ Failed: <b>{total_failed}</b>\n"
        f"📬 Recipients: {', '.join(recipients)}\n\n"
        f"<i>Report logs saved to database</i>"
    )

    await query.edit_message_text(summary, reply_markup=get_main_keyboard(), parse_mode='HTML')
    context.user_data.clear()
async def monitoring_worker(context: ContextTypes.DEFAULT_TYPE):
    """Background task to check monitored targets"""
    targets = get_monitored_targets()

    if not targets:
        return

    accounts = get_enabled_accounts()
    if not accounts:
        return

    client = await get_client(accounts[0][0])
    if not client:
        return

    for target in targets:
        t_id, t_username, t_tele_id, last_status, last_check, is_active = target

        result = await check_target_exists(client, t_username or str(t_tele_id))

        if result.get('exists'):
            status = "active"
        else:
            status = "banned/not_found"

        update_monitoring_status(t_tele_id, status)

        if status == "banned/not_found" and not is_target_banned_notified(t_tele_id):
            for admin_id in ADMIN_IDS:
                await context.bot.send_message(
                    admin_id,
                    f"🚨 <b>MONITORING ALERT!</b>\n\n"
                    f"Target: <code>{t_username or t_tele_id}</code>\n"
                    f"Status: <b>BANNED / NOT FOUND</b>\n"
                    f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
                    parse_mode='HTML'
                )
            set_target_notified(t_tele_id, True)
        elif status == "active":
            set_target_notified(t_tele_id, False)

    await client.disconnect()
async def execute_report_action(update: Update, context: ContextTypes.DEFAULT_TYPE, category: str, subcategory: str, comment: str, report_count: int, is_story: bool = False):
    query = update.callback_query
    target = context.user_data.get('report_target')
    target_name = context.user_data.get('report_target_name', target)
    target_id = context.user_data.get('target_id')
    account_id = context.user_data.get('account_id')
    use_all = context.user_data.get('all_accounts', False)
    msg_id = context.user_data.get('msg_id', 0)

    if not target:
        await query.edit_message_text("❌ Target not found!", reply_markup=get_main_keyboard())
        return

    if use_all:
        accounts = get_enabled_accounts()
        account_ids = [a[0] for a in accounts]
    else:
        account_ids = [account_id]

    if not account_ids:
        await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
        return

    total_reports = report_count * len(account_ids)
    attack_start_time = time.time()
    start_time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    await query.edit_message_text(
        f"<b>🚀 STARTING REPORT</b>\n\n"
        f"🎯 Target: <code>{target_name}</code>\n"
        f"📊 Total reports: <b>{total_reports}</b>\n"
        f"📱 Accounts: <b>{len(account_ids)}</b>\n"
        f"🔢 Per account: <b>{report_count}</b>\n"
        f"📖 Story Report: <b>{'Yes' if is_story else 'No'}</b>\n"
        f"⏰ Started: <code>{start_time_str}</code>\n\n"
        f"⏳ Checking target existence...",
        parse_mode='HTML'
    )

    first_client = await get_client(account_ids[0])
    if first_client:
        target_check = await check_target_exists(first_client, target)
        await first_client.disconnect()

        if not target_check.get('exists'):
            await query.edit_message_text(
                f"<b>❌ TARGET NOT FOUND!</b>\n\n"
                f"Target: <code>{target_name}</code>\n"
                f"Error: {target_check.get('error', 'Unknown error')}\n\n"
                f"Please check the target and try again.",
                reply_markup=get_main_keyboard(),
                parse_mode='HTML'
            )
            return

        target_id = target_check.get('id')
        context.user_data['target_id'] = target_id

        target_info = f"\n<b>✅ Target Info:</b>\n"
        target_info += f"• Type: {target_check.get('type', 'Unknown')}\n"
        if target_check.get('name'):
            target_info += f"• Name: {target_check.get('name')}\n"
        if target_check.get('title'):
            target_info += f"• Title: {target_check.get('title')}\n"
        if target_check.get('username'):
            target_info += f"• Username: {target_check.get('username')}\n"

        await query.edit_message_text(
            f"<b>🚀 STARTING REPORT</b>\n\n"
            f"🎯 Target: <code>{target_name}</code>\n"
            f"🆔 Target ID: <code>{target_id}</code>\n"
            f"📊 Total reports: <b>{total_reports}</b>\n"
            f"📱 Accounts: <b>{len(account_ids)}</b>\n"
            f"🔢 Per account: <b>{report_count}</b>\n"
            f"⏰ Started: <code>{start_time_str}</code>\n"
            f"{target_info}\n"
            f"⏳ Sending reports...",
            parse_mode='HTML'
        )

    success_count = 0
    failed_count = 0
    current_report = 0

    for aid in account_ids:
        client = await get_client(aid)
        if not client:
            continue

        acc = get_account_by_id(aid)
        phone = acc[3] if acc else "Unknown"
        account_success = 0

        for i in range(report_count):
            current_report += 1

            try:
                peer = await resolve_target(client, target)
                message_ids = [msg_id] if msg_id and msg_id != 0 else []

                result = await send_report_action(client, peer, message_ids, category, comment, is_story)

                if result.get('success'):
                    account_success += 1
                    success_count += 1
                else:
                    failed_count += 1

                if current_report % 3 == 0 or current_report == total_reports:
                    elapsed = int(time.time() - attack_start_time)
                    await query.edit_message_text(
                        f"<b>📊 REPORTING PROGRESS</b>\n\n"
                        f"Progress: <b>{current_report}/{total_reports}</b>\n"
                        f"✅ Success: <b>{success_count}</b>\n"
                        f"❌ Failed: <b>{failed_count}</b>\n"
                        f"⏱️ Elapsed: <code>{format_duration(elapsed)}</code>\n\n"
                        f"⏳ Continuing...",
                        parse_mode='HTML'
                    )

                await asyncio.sleep(random.uniform(1, 3))

            except Exception as e:
                failed_count += 1

        if account_success > 0:
            update_account_stats(aid, True)
        await client.disconnect()
        await asyncio.sleep(2)

    attack_end_time = time.time()
    duration_seconds = int(attack_end_time - attack_start_time)
    end_time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    for aid in account_ids:
        add_report_log(aid, target, target_name, target_id, category, subcategory, comment, report_count, is_story,
                      "success" if success_count > 0 else "failed", duration_seconds)

    summary = (
        f"<b>✅ REPORT COMPLETED!</b>\n\n"
        f"🎯 Target: <code>{target_name}</code>\n"
        f"🆔 Target ID: <code>{target_id if target_id else 'Unknown'}</code>\n"
        f"📂 {LEVEL_1_CATEGORIES.get(category, category)} → {subcategory}\n"
        f"✅ Successful: <b>{success_count}</b>\n"
        f"❌ Failed: <b>{failed_count}</b>\n"
        f"📊 Total: <b>{success_count + failed_count}</b>\n"
        f"⏰ Started: <code>{start_time_str}</code>\n"
        f"⏰ Finished: <code>{end_time_str}</code>\n"
        f"⏱️ Duration: <b>{format_duration(duration_seconds)}</b>"
    )

    await query.edit_message_text(summary, reply_markup=get_main_keyboard(), parse_mode='HTML')
    context.user_data.clear()
async def handle_check_all_status(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()

    await query.edit_message_text(
        "<b>📊 CHECKING ALL ACCOUNTS STATUS</b>\n\n"
        "⏳ Checking Telegram accounts...\n"
        "This may take a few moments.",
        parse_mode='HTML'
    )

    telegram_results = await check_all_telegram_accounts()

    email_results = check_all_email_accounts()

    report = "<b>📊 ACCOUNT STATUS REPORT</b>\n\n"

    report += "<b>🤖 TELEGRAM ACCOUNTS:</b>\n"
    for r in telegram_results:
        if r["status"] == "active":
            icon = "✅"
        elif r["status"] == "banned":
            icon = "🚫"
        elif r["status"] == "flood_wait":
            icon = "⏳"
        else:
            icon = "❌"
        report += f"{icon} <code>{r['phone']}</code> - {r['message']}\n"

    report += "\n<b>📧 EMAIL ACCOUNTS:</b>\n"
    for r in email_results:
        if r["status"] == "valid":
            icon = "✅"
        elif r["status"] == "invalid":
            icon = "❌"
        elif r["status"] == "disabled":
            icon = "⏸️"
        else:
            icon = "⚠️"
        report += f"{icon} <code>{r['email']}</code> - {r['message']}\n"

    report += "\n<i>Use /start to return to main menu</i>"

    await query.edit_message_text(report, parse_mode='HTML', reply_markup=get_main_keyboard())
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if update.effective_user.id not in ADMIN_IDS:
        await update.message.reply_text("❌ Unauthorized!")
        return

    await update.message.reply_text(
        "<b>🤖 REPORTER PRO BOT - ULTIMATE VERSION with EMAIL</b>\n\n"
        "<b>✅ Features:</b>\n"
        "• Full 2FA Login Support\n"
        "• Proxy Support (SOCKS5/HTTP)\n"
        "• Multi-User Report\n"
        "• Story Report\n"
        "• Multi-Message Report\n"
        "• Target Existence Check\n"
        "• Monitoring System (Auto ban detection)\n"
        "• Attack Timer & Duration\n"
        "• Batch Reporting (1-50 reports)\n"
        "• Email Reporting via Gmail SMTP\n"
        "• Email Account Status Check\n"
        "• All Accounts Status Check\n\n"
        "<b>📌 Use the buttons below to get started:</b>",
        reply_markup=get_main_keyboard(),
        parse_mode='HTML'
    )
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()
    data = query.data
    user_id = update.effective_user.id

    if user_id not in ADMIN_IDS:
        await query.edit_message_text("❌ Unauthorized!")
        return

    if data == "main_menu":
        await query.edit_message_text(
            "<b>📱 Main Menu</b>\n\nSelect an option:",
            reply_markup=get_main_keyboard(),
            parse_mode='HTML'
        )

    elif data == "check_all_status":
        await handle_check_all_status(update, context)

    elif data == "menu_email_report":
        await query.edit_message_text(
            "<b>📧 Email Reporting System</b>\n\n"
            "Send reports to Telegram support emails.\n\n"
            "<b>Target emails:</b>\n"
            "• abuse@telegram.org\n"
            "• support@telegram.org\n"
            "• stopCA@telegram.org\n"
            "• dmca@telegram.org\n\n"
            "Select an option:",
            reply_markup=get_email_main_keyboard(),
            parse_mode='HTML'
        )

    elif data == "add_email_account":
        context.user_data['adding_email'] = True
        context.user_data['email_step'] = 'email'
        await query.edit_message_text(
            "<b>➕ Add Email Account</b>\n\n"
            "<b>Send your email address:</b>\n\n"
            "<i>Example: example@gmail.com</i>\n\n"
            "<b>⚠️ Note:</b> You need an <b>App Password</b> from Google, not your regular password.\n"
            "Get it at: myaccount.google.com/apppasswords",
            parse_mode='HTML'
        )
        return ADD_EMAIL

    elif data == "toggle_email_accounts":
        keyboard = get_toggle_email_keyboard()
        if not keyboard:
            await query.edit_message_text("❌ No email accounts found!", reply_markup=get_email_main_keyboard())
            return
        await query.edit_message_text(
            "<b>🔘 Toggle Email Accounts</b>\n\n"
            "✅ = Enabled | ❌ = Disabled | ⚠️ = Invalid\n\n"
            "📌 Click any account to toggle ON/OFF:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("toggle_email_"):
        acc_id = int(data.split("_")[2])
        new_status = toggle_email_account_enabled(acc_id)
        keyboard = get_toggle_email_keyboard()
        if keyboard:
            await query.edit_message_reply_markup(reply_markup=keyboard)
            await query.answer(f"Email account {'enabled' if new_status else 'disabled'}")

    elif data.startswith("toggle_email_page_"):
        page = int(data.split("_")[3])
        keyboard = get_toggle_email_keyboard(page=page)
        if keyboard:
            await query.edit_message_reply_markup(reply_markup=keyboard)

    elif data == "email_logs":
        conn = sqlite3.connect('reporter.db')
        logs = conn.execute(
            "SELECT recipient, target, category, status, timestamp FROM email_report_logs ORDER BY timestamp DESC LIMIT 20"
        ).fetchall()
        conn.close()

        if not logs:
            await query.edit_message_text("📋 No email logs yet!", reply_markup=get_email_main_keyboard())
            return

        msg = "<b>📧 EMAIL REPORT LOGS</b>\n\n"
        for log in logs:
            recipient, target, category, status, ts = log
            icon = "✅" if "success" in str(status) else "❌"
            msg += f"{icon} <code>{target[:20]}</code> → {recipient}\n"
            msg += f"   📂 {category} | {ts[:16]}\n\n"

        await query.edit_message_text(msg, reply_markup=get_email_main_keyboard(), parse_mode='HTML')

    elif data == "start_email_report":
        keyboard = get_email_accounts_keyboard(action="email_report")
        if not keyboard:
            await query.edit_message_text("❌ No email accounts! Please add one first.", reply_markup=get_email_main_keyboard())
            return
        await query.edit_message_text(
            "<b>📧 Send Email Report</b>\n\nSelect email account to send from:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("email_report_email_"):
        acc_id = int(data.split("_")[3])
        context.user_data['email_account_id'] = acc_id
        context.user_data['email_all_accounts'] = False
        await query.edit_message_text(
            "<b>🎯 Send Target</b>\n\n"
            "Send the username, ID, or link of the user/channel you want to report:\n\n"
            "<b>Examples:</b>\n"
            "• <code>@spammer</code>\n"
            "• <code>123456789</code>\n"
            "• <code>https://t.me/username</code>",
            parse_mode='HTML'
        )
        return EMAIL_REPORT_TARGETS

    elif data == "email_report_all":
        context.user_data['email_all_accounts'] = True
        await query.edit_message_text(
            "<b>🎯 Send Target</b>\n\n"
            "Send the username, ID, or link of the user/channel you want to report:",
            parse_mode='HTML'
        )
        return EMAIL_REPORT_TARGETS

    elif data.startswith("email_recipient_"):
        recipient = data.replace("email_recipient_", "")
        if recipient == "all":
            context.user_data['email_recipients'] = EMAIL_REPORT_RECIPIENTS.copy()
        else:
            context.user_data['email_recipients'] = [recipient]

        await query.edit_message_text(
            f"<b>📋 Select Category</b>\n\n"
            f"Selected recipients: {', '.join(context.user_data['email_recipients'])}\n\n"
            f"Choose report category:",
            reply_markup=get_email_categories_keyboard(),
            parse_mode='HTML'
        )

    elif data.startswith("email_cat_"):
        category = data.replace("email_cat_", "")
        context.user_data['email_category'] = category

        await query.edit_message_text(
            f"<b>📝 Email Template for {LEVEL_1_CATEGORIES.get(category, category)}</b>\n\n"
            f"<b>Default template:</b>\n"
            f"<code>{EMAIL_TEMPLATES.get(category, EMAIL_TEMPLATES['other'])['body'][:200]}...</code>\n\n"
            f"Do you want to use the default template or write a custom message?",
            reply_markup=get_email_template_choice_keyboard(),
            parse_mode='HTML'
        )

    elif data == "email_template_default":
        context.user_data['email_custom_body'] = None
        await query.edit_message_text(
            "<b>🔢 How many emails to send?</b>\n\n"
            "<i>Default is 2 per recipient per account.</i>\n"
            "Send a number (1-10):",
            parse_mode='HTML'
        )
        return EMAIL_REPORT_COUNT

    elif data == "email_template_custom":
        context.user_data['email_custom_body'] = ""
        await query.edit_message_text(
            "<b>✏️ Write your custom email body</b>\n\n"
            "Send your message. Use <code>{target}</code> as placeholder for the target.\n\n"
            "<b>Example:</b>\n"
            "<code>Please ban {target} for spam...</code>\n\n"
            "Send <code>END</code> when finished:",
            parse_mode='HTML'
        )
        return EMAIL_REPORT_CONFIRM

    elif data == "email_confirm_yes":
        await send_email_reports(update, context)

    elif data == "email_confirm_edit":
        await query.edit_message_text(
            "<b>✏️ Edit Email Body</b>\n\n"
            "Send your custom message. Use <code>{target}</code> as placeholder.\n\n"
            "Send <code>END</code> when finished:",
            parse_mode='HTML'
        )
        return EMAIL_REPORT_CONFIRM

    elif data == "email_confirm_no":
        context.user_data.clear()
        await query.edit_message_text("❌ Cancelled.", reply_markup=get_email_main_keyboard())

    elif data == "menu_accounts":
        keyboard = [
            [InlineKeyboardButton("➕ Add Account", callback_data="add_account", style="success")],
            [InlineKeyboardButton("🔘 Toggle Accounts", callback_data="toggle_accounts", style="primary")],
            [InlineKeyboardButton("📋 List Accounts", callback_data="list_accounts", style="primary")],
            [InlineKeyboardButton("🔙 Back", callback_data="main_menu", style="danger")]
        ]
        await query.edit_message_text(
            "<b>📋 Account Manager</b>\n\nSelect an option:",
            reply_markup=InlineKeyboardMarkup(keyboard),
            parse_mode='HTML'
        )

    elif data == "toggle_accounts":
        keyboard = get_toggle_accounts_keyboard()
        if not keyboard:
            await query.edit_message_text("❌ No accounts found!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>🔘 Toggle Accounts</b>\n\n"
            "✅ = Enabled | ❌ = Disabled | 🚫 = Banned | ⚠️ = No session | 🔒 = Proxy\n\n"
            "📌 Click any account to toggle ON/OFF:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("toggle_acc_"):
        acc_id = int(data.split("_")[2])
        new_status = toggle_account_enabled(acc_id)
        keyboard = get_toggle_accounts_keyboard()
        if keyboard:
            await query.edit_message_reply_markup(reply_markup=keyboard)
            await query.answer(f"Account {'enabled' if new_status else 'disabled'}")

    elif data.startswith("toggle_page_"):
        page = int(data.split("_")[2])
        keyboard = get_toggle_accounts_keyboard(page=page)
        if keyboard:
            await query.edit_message_reply_markup(reply_markup=keyboard)

    elif data == "save_and_next":
        enabled_accounts = get_enabled_accounts()
        if not enabled_accounts:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            f"✅ Saved! {len(enabled_accounts)} account(s) enabled.\n\n📌 Select an action:",
            reply_markup=get_main_keyboard()
        )

    elif data == "add_account":
        context.user_data.clear()
        context.user_data['adding'] = True
        context.user_data['step'] = 'api_id'
        await query.edit_message_text(
            "<b>➕ ADD ACCOUNT</b> (Step 1/5)\n\n"
            "📝 Send your <b>API ID</b>:\n"
            "<i>Get it from my.telegram.org</i>",
            parse_mode='HTML'
        )
        return ADD_API_ID

    elif data == "list_accounts":
        accounts = get_all_accounts()
        if not accounts:
            await query.edit_message_text("❌ No accounts found!", reply_markup=get_main_keyboard())
            return

        msg = "<b>📱 YOUR ACCOUNTS</b>\n\n"
        for acc in accounts:
            acc_id, api_id, api_hash, phone, proxy, is_enabled, is_banned, rep, suc = acc

            if is_banned:
                icon = "🚫 BANNED"
            elif is_enabled:
                session_exists = os.path.exists(f"sessions/{phone}.session")
                icon = "✅ ENABLED" if session_exists else "⚠️ NO SESSION"
            else:
                icon = "❌ DISABLED"

            proxy_icon = " 🔒" if proxy else ""
            msg += f"{icon}{proxy_icon}\n📞 <code>{phone}</code>\n📊 Reports: {rep} | ✅ Success: {suc}\n\n"

        await query.edit_message_text(msg, reply_markup=get_main_keyboard(), parse_mode='HTML')

    elif data == "proxy_yes":
        context.user_data['add_proxy'] = True
        await query.edit_message_text(
            "<b>🔒 Send Proxy</b>\n\n"
            "Send proxy in format:\n"
            "<code>socks5://user:pass@host:port</code>\n\n"
            "Or send <code>none</code> to skip:",
            parse_mode='HTML'
        )
        return

    elif data == "proxy_no":
        context.user_data['add_proxy'] = False
        api_id = context.user_data.get('api_id')
        api_hash = context.user_data.get('api_hash')
        phone = context.user_data.get('phone')

        add_account(api_id, api_hash, phone, None)
        await query.edit_message_text("🔄 Sending verification code...")

        try:
            client = TelegramClient(f"sessions/{phone}", api_id, api_hash)
            await client.connect()
            result = await client.send_code_request(phone)

            context.user_data['client'] = client
            context.user_data['step'] = 'code'
            context.user_data['phone_code_hash'] = result.phone_code_hash

            await query.edit_message_text(
                "<b>📱 Step 4/5 - Send verification code:</b>\n\n"
                "<i>Check your Telegram for the code</i>",
                parse_mode='HTML'
            )
            return ADD_CODE
        except errors.PhoneNumberBannedError:
            await query.edit_message_text("❌ Phone is BANNED!", reply_markup=get_main_keyboard())
            context.user_data.clear()
        except Exception as e:
            await query.edit_message_text(f"❌ Error: {str(e)[:100]}")
            context.user_data.clear()

    elif data == "menu_send":
        keyboard = get_accounts_keyboard(action="send")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>✉️ Send Message</b>\n\nSelect account:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("send_acc_"):
        acc_id = int(data.split("_")[2])
        context.user_data['account_id'] = acc_id
        context.user_data['all_accounts'] = False
        context.user_data['action'] = 'send'
        await query.edit_message_text(
            "<b>🎯 Send Target</b>\n\n"
            "<b>You can send:</b>\n"
            "• <code>@username</code> - Username\n"
            "• <code>123456789</code> - User/Group ID\n"
            "• <code>https://t.me/username</code> - Chat link\n\n"
            "<b>Example:</b> <code>@durov</code>",
            parse_mode='HTML'
        )
        return SEND_TARGET

    elif data == "send_all":
        context.user_data['all_accounts'] = True
        context.user_data['action'] = 'send'
        await query.edit_message_text(
            "<b>🎯 Send Target</b>\n\n"
            "<b>You can send:</b>\n"
            "• <code>@username</code> - Username\n"
            "• <code>123456789</code> - User/Group ID\n"
            "• <code>https://t.me/username</code> - Chat link\n\n"
            "<b>Example:</b> <code>@durov</code>",
            parse_mode='HTML'
        )
        return SEND_TARGET

    elif data == "menu_report":
        keyboard = get_accounts_keyboard(action="report")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        context.user_data['report_mode'] = 'single'
        await query.edit_message_text(
            "<b>🚨 Select Account</b>\n\nSelect account to report from:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data == "menu_multi_user":
        context.user_data['report_mode'] = 'multi_user'
        keyboard = get_accounts_keyboard(action="report")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>👥 Multi User Report</b>\n\nSelect account(s):",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data == "menu_story":
        context.user_data['report_mode'] = 'story'
        keyboard = get_accounts_keyboard(action="report")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>📖 Story Report</b>\n\nSelect account(s):",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data == "menu_multi_message":
        context.user_data['report_mode'] = 'multi_message'
        keyboard = get_accounts_keyboard(action="report")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>📝 Multi Message Report</b>\n\nSelect account(s):",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("report_acc_"):
        acc_id = int(data.split("_")[2])
        context.user_data['account_id'] = acc_id
        context.user_data['all_accounts'] = False
        mode = context.user_data.get('report_mode', 'single')

        if mode == 'multi_user':
            await query.edit_message_text(
                "<b>👥 Multi User Report</b>\n\n"
                "Send usernames or IDs (one per line):\n\n"
                "<b>Example:</b>\n"
                "<code>@user1\n@user2\nhttps://t.me/user3</code>\n\n"
                "<i>You can mix usernames, IDs, and links</i>",
                parse_mode='HTML'
            )
            return REPORT_MULTI_USERS

        elif mode == 'story':
            context.user_data['is_story'] = True
            await query.edit_message_text(
                "<b>📖 Story Report</b>\n\n"
                "Send the username or link of the user whose story you want to report:\n\n"
                "<b>Example:</b> <code>@username</code>\n\n"
                "<i>Note: The story must be visible to your account</i>",
                parse_mode='HTML'
            )
            return REPORT_STORY

        elif mode == 'multi_message':
            await query.edit_message_text(
                "<b>📝 Multi Message Report</b>\n\n"
                "Send message links (one per line):\n\n"
                "<b>Example:</b>\n"
                "<code>https://t.me/channel/123\nhttps://t.me/another/456</code>",
                parse_mode='HTML'
            )
            return REPORT_MULTI_MESSAGE

        else:
            await query.edit_message_text(
                "<b>🎯 Send Target</b>\n\n"
                "<b>You can send:</b>\n"
                "• <code>@username</code> - Username\n"
                "• <code>123456789</code> - User/Group ID\n"
                "• <code>https://t.me/username/123</code> - Message link\n"
                "• <code>https://t.me/username</code> - Chat link\n\n"
                "<b>Example:</b> <code>https://t.me/durov/100</code>",
                parse_mode='HTML'
            )
            return REPORT_TARGET

    elif data == "report_all":
        context.user_data['all_accounts'] = True
        mode = context.user_data.get('report_mode', 'single')

        if mode == 'multi_user':
            await query.edit_message_text(
                "<b>👥 Multi User Report</b>\n\nSend usernames or IDs (one per line):",
                parse_mode='HTML'
            )
            return REPORT_MULTI_USERS
        elif mode == 'story':
            context.user_data['is_story'] = True
            await query.edit_message_text(
                "<b>📖 Story Report</b>\n\nSend the username or link:",
                parse_mode='HTML'
            )
            return REPORT_STORY
        elif mode == 'multi_message':
            await query.edit_message_text(
                "<b>📝 Multi Message Report</b>\n\nSend message links (one per line):",
                parse_mode='HTML'
            )
            return REPORT_MULTI_MESSAGE
        else:
            await query.edit_message_text(
                "<b>🎯 Send Target</b>\n\nSend username, ID, or message link:",
                parse_mode='HTML'
            )
            return REPORT_TARGET

    elif data == "menu_block":
        keyboard = get_accounts_keyboard(action="block")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>🚫 Block User</b>\n\nSelect account:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("block_acc_"):
        acc_id = int(data.split("_")[2])
        context.user_data['account_id'] = acc_id
        context.user_data['all_accounts'] = False
        context.user_data['action'] = 'block'
        await query.edit_message_text(
            "<b>🚫 Send Username</b>\n\n"
            "<b>You can send:</b>\n"
            "• <code>@username</code> - Username\n"
            "• <code>123456789</code> - User ID\n\n"
            "<b>Example:</b> <code>@spammer</code>",
            parse_mode='HTML'
        )
        return BLOCK_TARGET

    elif data == "block_all":
        context.user_data['all_accounts'] = True
        context.user_data['action'] = 'block'
        await query.edit_message_text(
            "<b>🚫 Send Username</b>\n\nSend username to block:",
            parse_mode='HTML'
        )
        return BLOCK_TARGET

    elif data == "menu_bulk":
        keyboard = get_accounts_keyboard(action="bulk")
        if not keyboard:
            await query.edit_message_text("❌ No enabled accounts!", reply_markup=get_main_keyboard())
            return
        await query.edit_message_text(
            "<b>📊 Bulk Report</b>\n\nSelect account:",
            reply_markup=keyboard,
            parse_mode='HTML'
        )

    elif data.startswith("bulk_acc_"):
        acc_id = int(data.split("_")[2])
        context.user_data['account_id'] = acc_id
        context.user_data['all_accounts'] = False
        context.user_data['action'] = 'bulk'
        await query.edit_message_text(
            "<b>📊 Send Targets</b>\n\n"
            "Send targets one per line:\n\n"
            "<code>@user1\n@user2\nhttps://t.me/channel/123\n123456789</code>",
            parse_mode='HTML'
        )
        return BULK_TARGETS

    elif data == "bulk_all":
        context.user_data['all_accounts'] = True
        context.user_data['action'] = 'bulk'
        await query.edit_message_text(
            "<b>📊 Send Targets</b>\n\nSend targets one per line:",
            parse_mode='HTML'
        )
        return BULK_TARGETS

    elif data == "menu_monitoring":
        await query.edit_message_text(
            "<b>👁️ Monitoring System</b>\n\n"
            "Monitor targets for ban/delete status.\n\n"
            "• Add a target to monitor\n"
            f"• Current check interval: <b>{get_monitor_interval()} minutes</b>\n"
            "• Get notified when target is banned\n\n"
            "Select an option:",
            reply_markup=get_monitoring_keyboard(),
            parse_mode='HTML'
        )

    elif data == "monitor_add":
        context.user_data['monitor_action'] = 'add'
        await query.edit_message_text(
            "<b>➕ Add to Monitoring</b>\n\n"
            "Send the target username or ID to monitor:\n\n"
            "<b>Examples:</b>\n"
            "• <code>@username</code>\n"
            "• <code>123456789</code>\n"
            "• <code>https://t.me/username</code>\n\n"
            "<i>The system will check this target periodically and notify you if it gets banned.</i>",
            parse_mode='HTML'
        )
        return MONITOR_TARGET

    elif data == "monitor_list":
        targets = get_monitored_targets()
        if not targets:
            await query.edit_message_text("📋 No targets in monitoring list!", reply_markup=get_monitoring_keyboard())
            return

        msg = "<b>👁️ Monitored Targets</b>\n\n"
        for t in targets:
            t_id, t_username, t_tele_id, last_status, last_check, is_active = t
            status_icon = "🟢" if last_status == "active" else "🔴" if last_status else "⚪"
            status_text = last_status if last_status else "Unknown"
            msg += f"{status_icon} <code>{t_username or t_tele_id}</code>\n"
            msg += f"   Status: {status_text}\n"
            msg += f"   Last check: {last_check[:16] if last_check else 'Never'}\n\n"

        await query.edit_message_text(msg, reply_markup=get_monitoring_keyboard(), parse_mode='HTML')

    elif data == "monitor_remove":
        targets = get_monitored_targets()
        if not targets:
            await query.edit_message_text("📋 No targets in monitoring list!", reply_markup=get_main_keyboard())
            return

        keyboard = []
        for t in targets:
            t_id, t_username, t_tele_id, _, _, _ = t
            name = t_username or str(t_tele_id)
            keyboard.append([InlineKeyboardButton(f"❌ {name}", callback_data=f"monitor_del_{t_tele_id}", style="danger")])
        keyboard.append([InlineKeyboardButton("🔙 Back", callback_data="menu_monitoring", style="primary")])

        await query.edit_message_text(
            "<b>🗑️ Remove from Monitoring</b>\n\nSelect target to remove:",
            reply_markup=InlineKeyboardMarkup(keyboard),
            parse_mode='HTML'
        )

    elif data.startswith("monitor_del_"):
        target_id = data.split("_")[2]
        remove_from_monitoring(target_id)
        await query.edit_message_text("✅ Target removed from monitoring!", reply_markup=get_monitoring_keyboard())

    elif data == "monitor_check_now":
        await query.edit_message_text("🔄 Checking monitored targets...")
        await monitoring_worker(context)
        await query.edit_message_text("✅ Check completed!", reply_markup=get_monitoring_keyboard())

    elif data == "monitor_interval":
        context.user_data['monitor_action'] = 'interval'
        await query.edit_message_text(
            "<b>⚙️ Monitoring Interval</b>\n\n"
            "Send the interval in minutes (1-1440):\n\n"
            "• <b>1</b> - Check every minute (intensive)\n"
            "• <b>5</b> - Check every 5 minutes (recommended)\n"
            "• <b>60</b> - Check every hour\n"
            "• <b>1440</b> - Check once per day\n\n"
            f"<i>Current interval: {get_monitor_interval()} minutes</i>",
            parse_mode='HTML'
        )
        return MONITOR_INTERVAL

    elif data == "menu_stats":
        total, enabled, reports, email_total, email_enabled, email_sent = get_stats()
        await query.edit_message_text(
            f"<b>📈 STATISTICS</b>\n\n"
            f"<b>🤖 TELEGRAM ACCOUNTS:</b>\n"
            f"📱 Total: <b>{total}</b>\n"
            f"🟢 Enabled: <b>{enabled}</b>\n"
            f"📝 Total reports: <b>{reports}</b>\n\n"
            f"<b>📧 EMAIL ACCOUNTS:</b>\n"
            f"📧 Total: <b>{email_total}</b>\n"
            f"🟢 Enabled/Valid: <b>{email_enabled}</b>\n"
            f"📨 Emails sent: <b>{email_sent}</b>",
            reply_markup=get_main_keyboard(),
            parse_mode='HTML'
        )

    elif data == "menu_logs":
        conn = sqlite3.connect('reporter.db')
        logs = conn.execute(
            "SELECT target_name, category, subcategory, comment, report_count, is_story, status, duration_seconds FROM report_logs ORDER BY timestamp DESC LIMIT 15"
        ).fetchall()
        conn.close()

        if not logs:
            await query.edit_message_text("📋 No logs yet!", reply_markup=get_main_keyboard())
            return

        msg = "<b>📋 RECENT REPORTS</b>\n\n"
        for log in logs:
            target_name, cat, sub, comment, rep_count, is_story, status, duration = log
            icon = "✅" if "success" in str(status) else "❌"
            story_icon = "📖" if is_story else ""
            msg += f"{icon}{story_icon} <code>{target_name[:25]}</code> x{rep_count}\n"
            msg += f"   📂 {cat}/{sub}\n"
            if duration:
                msg += f"   ⏱️ Duration: {format_duration(duration)}\n"
            msg += "\n"

        await query.edit_message_text(msg, reply_markup=get_main_keyboard(), parse_mode='HTML')

    elif data == "menu_settings":
        await query.edit_message_text(
            "<b>⚙️ Settings</b>\n\nSelect an option:",
            reply_markup=get_settings_keyboard(),
            parse_mode='HTML'
        )

    elif data == "export_accounts":
        accounts = get_all_accounts()
        export = [{"api_id": a[1], "api_hash": a[2], "phone": a[3], "proxy": a[4]} for a in accounts]
        with open("accounts_export.json", "w") as f:
            json.dump(export, f, indent=2)
        await context.bot.send_document(
            chat_id=user_id,
            document=open("accounts_export.json", "rb"),
            filename="accounts_export.json"
        )
        os.remove("accounts_export.json")
        await query.edit_message_text("✅ Exported!", reply_markup=get_main_keyboard())

    elif data == "import_accounts":
        await query.edit_message_text(
            "<b>📥 Import Accounts</b>\n\nSend JSON file with this format:\n\n"
            "<code>[{\"api_id\": 12345, \"api_hash\": \"hash\", \"phone\": \"+123456789\", \"proxy\": \"socks5://host:port\"}]</code>\n\n"
            "<i>Proxy is optional</i>",
            parse_mode='HTML'
        )
        return

    elif data == "set_proxy":
        context.user_data['setting_proxy'] = True
        await query.edit_message_text(
            "<b>🔒 Set Proxy for Account</b>\n\n"
            "First, select an account:\n\n"
            "<i>Then send proxy in format:</i>\n"
            "<code>socks5://user:pass@host:port</code>\n"
            "<code>socks5://host:port</code>\n"
            "<code>http://user:pass@host:port</code>",
            reply_markup=get_accounts_keyboard(action="proxy"),
            parse_mode='HTML'
        )

    elif data.startswith("proxy_acc_"):
        acc_id = int(data.split("_")[2])
        context.user_data['proxy_account_id'] = acc_id
        await query.edit_message_text(
            "<b>🔒 Send Proxy</b>\n\n"
            "Send proxy in format:\n"
            "<code>socks5://user:pass@host:port</code>\n\n"
            "Or send <code>none</code> to remove proxy:",
            parse_mode='HTML'
        )
        return

    elif data == "clear_logs":
        conn = sqlite3.connect('reporter.db')
        conn.execute("DELETE FROM report_logs WHERE date(timestamp) < date('now', '-30 days')")
        conn.commit()
        conn.close()
        await query.edit_message_text("🗑️ Old logs cleared!", reply_markup=get_main_keyboard())

    elif data == "menu_help":
        await query.edit_message_text(
            "<b>❓ Help & Support</b>\n\nSelect a topic:",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_report":
        await query.edit_message_text(
            "<b>📖 How to Report</b>\n\n"
            "<b>You can send targets in these formats:</b>\n\n"
            "1️⃣ <b>Username:</b> <code>@username</code>\n"
            "2️⃣ <b>User ID:</b> <code>123456789</code>\n"
            "3️⃣ <b>Chat ID:</b> <code>-100123456789</code>\n"
            "4️⃣ <b>Message Link (Auto extracts):</b>\n"
            "   <code>https://t.me/username/123</code>\n\n"
            "<b>📌 Note:</b> The bot automatically checks if the target exists before reporting!\n\n"
            "<b>💡 Tip:</b> You can report users, groups, channels, or specific messages.",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_send":
        await query.edit_message_text(
            "<b>📝 How to Send Message</b>\n\n"
            "<b>You can send to these target formats:</b>\n\n"
            "• <b>Username:</b> <code>@username</code>\n"
            "• <b>User ID:</b> <code>123456789</code>\n"
            "• <b>Chat ID:</b> <code>-100123456789</code>\n\n"
            "<b>📌 Process:</b>\n"
            "1. Select account\n"
            "2. Send target\n"
            "3. Send your message\n"
            "4. Enter number of times (1-50)\n\n"
            "<b>⚠️ Warning:</b> Sending too many messages may get your account limited!",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_block":
        await query.edit_message_text(
            "<b>🚫 How to Block</b>\n\n"
            "<b>You can block these target formats:</b>\n\n"
            "• <b>Username:</b> <code>@username</code>\n"
            "• <b>User ID:</b> <code>123456789</code>\n\n"
            "<b>📌 Note:</b> Blocking will prevent the user from contacting your reporting accounts.",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_multi":
        await query.edit_message_text(
            "<b>👥 Multi User Report</b>\n\n"
            "<b>Report multiple users at once!</b>\n\n"
            "<b>📌 How to use:</b>\n"
            "1. Select account(s)\n"
            "2. Send usernames/IDs (one per line)\n\n"
            "<b>Example:</b>\n"
            "<code>@user1\n"
            "@user2\n"
            "https://t.me/user3\n"
            "123456789</code>\n\n"
            "<b>⚠️ Note:</b> All targets will be reported with the same reason and report count.",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_monitor":
        await query.edit_message_text(
            "<b>👁️ Monitoring System</b>\n\n"
            "<b>Monitor targets for ban/delete status!</b>\n\n"
            "<b>📌 How it works:</b>\n"
            "1. Add a target to monitoring\n"
            f"2. System checks every {get_monitor_interval()} minutes\n"
            "3. You get notified when target is banned/deleted\n\n"
            "<b>💡 Tip:</b> The system checks by User ID, so username changes won't affect monitoring!",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_email":
        await query.edit_message_text(
            "<b>📧 Email Reporting</b>\n\n"
            "<b>Send email reports to Telegram support!</b>\n\n"
            "<b>📌 How it works:</b>\n"
            "1. Add Gmail account (with App Password)\n"
            "2. Select target (username/ID/link)\n"
            "3. Choose category (auto-fills template)\n"
            "4. Select recipients (or all 4)\n"
            "5. Confirm and send\n\n"
            "<b>⚠️ Note:</b> Emails are sent with delay to avoid spam detection.\n\n"
            "<b>🔑 App Password:</b> Get from myaccount.google.com/apppasswords",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "help_proxy":
        await query.edit_message_text(
            "<b>🔒 Proxy Setup</b>\n\n"
            "<b>Protect your accounts with proxies!</b>\n\n"
            "<b>Supported formats:</b>\n"
            "• <code>socks5://user:pass@host:port</code>\n"
            "• <code>socks5://host:port</code>\n"
            "• <code>http://user:pass@host:port</code>\n"
            "• <code>socks4://host:port</code>\n\n"
            "<b>📌 How to set:</b>\n"
            "1. Go to Settings → Set Proxy\n"
            "2. Select an account\n"
            "3. Send proxy string\n\n"
            "<b>💡 Tip:</b> Each account can have its own proxy!",
            reply_markup=get_help_keyboard(),
            parse_mode='HTML'
        )

    elif data == "support":
        await query.edit_message_text(
            "<b>🆘 Support</b>\n\n"
            "Contact the developer for help, bug reports, or feature requests:\n\n"
            "<b>👨‍💻 Developer:</b> @MrEsfelurm\n\n"
            "Click the button below to send a message:",
            reply_markup=InlineKeyboardMarkup([
                [InlineKeyboardButton("📩 Contact Support", url="https://t.me/MrEsfelurm", style="danger")],
                [InlineKeyboardButton("🔙 Back", callback_data="menu_help", style="primary")]
            ]),
            parse_mode='HTML'
        )

    elif data.startswith("cat_"):
        category = data.replace("cat_", "")
        context.user_data['report_category'] = category
        await query.edit_message_text(
            f"<b>📂 Select subcategory:</b>",
            reply_markup=get_level_2_keyboard(category),
            parse_mode='HTML'
        )

    elif data == "back_categories":
        await query.edit_message_text(
            "<b>📋 Select category:</b>",
            reply_markup=get_level_1_keyboard(),
            parse_mode='HTML'
        )

    elif data.startswith("sub_"):
        parts = data.split("_")
        category = parts[1]
        subcategory = "_".join(parts[2:])
        context.user_data['report_subcategory'] = subcategory

        if category in REQUIRE_COMMENT:
            await query.edit_message_text(
                "<b>💬 Do you want to add a comment?</b>\n\n"
                "<i>Comment is optional but recommended for this category.</i>",
                reply_markup=get_comment_choice_keyboard(),
                parse_mode='HTML'
            )
        else:
            context.user_data['report_comment'] = ""
            await query.edit_message_text(
                "<b>🔢 How many reports?</b> (1-50):",
                parse_mode='HTML'
            )
            return REPORT_COUNT

    elif data == "comment_yes":
        context.user_data['awaiting_comment'] = True
        await query.edit_message_text(
            "<b>💬 Send your comment:</b>\n\n"
            "<i>Your comment will be sent with the report.</i>",
            parse_mode='HTML'
        )
        return REPORT_COMMENT

    elif data == "comment_no":
        context.user_data['report_comment'] = ""
        await query.edit_message_text(
            "<b>🔢 How many reports?</b> (1-50):",
            parse_mode='HTML'
        )
        return REPORT_COUNT

    elif data == "confirm_yes":
        category = context.user_data.get('report_category')
        subcategory = context.user_data.get('report_subcategory')
        comment = context.user_data.get('report_comment', '')
        report_count = context.user_data.get('report_count', 1)
        is_story = context.user_data.get('is_story', False)
        await execute_report_action(update, context, category, subcategory, comment, report_count, is_story)

    elif data == "confirm_no":
        context.user_data.clear()
        await query.edit_message_text("❌ Cancelled.", reply_markup=get_main_keyboard())

    elif data == "confirm_change":
        await query.edit_message_text(
            "<b>📋 Select new category:</b>",
            reply_markup=get_level_1_keyboard(),
            parse_mode='HTML'
        )

    elif data.startswith("send_page_") or data.startswith("report_page_") or data.startswith("block_page_") or data.startswith("bulk_page_") or data.startswith("proxy_page_") or data.startswith("email_report_page_"):
        parts = data.split("_")
        action = parts[0]
        page = int(parts[2])

        if action == "email":
            keyboard = get_email_accounts_keyboard(action="email_report", page=page)
        else:
            keyboard = get_accounts_keyboard(action=action, page=page)

        if keyboard:
            await query.edit_message_text("📌 Select account:", reply_markup=keyboard)
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    if user_id not in ADMIN_IDS:
        return

    text = update.message.text.strip()

    if context.user_data.get('adding_email'):
        step = context.user_data.get('email_step')

        if step == 'email':
            if '@' not in text or '.' not in text:
                await update.message.reply_text("❌ Invalid email format! Send a valid email address:")
                return ADD_EMAIL
            context.user_data['email_address'] = text
            context.user_data['email_step'] = 'password'
            await update.message.reply_text(
                "<b>🔑 Send App Password</b>\n\n"
                "Send your Gmail App Password (not your regular password).\n\n"
                "<i>Get it from: myaccount.google.com/apppasswords</i>",
                parse_mode='HTML'
            )
            return ADD_EMAIL_PASSWORD

        elif step == 'password':
            email = context.user_data.get('email_address')
            password = text
            await update.message.reply_text("🔄 Testing email connection...")
            success, msg = await test_email_connection(email, password)

            if success:
                add_email_account(email, password)
                await update.message.reply_text(
                    f"✅ Email account <code>{email}</code> added successfully!\n\n"
                    f"Test result: {msg}",
                    reply_markup=get_email_main_keyboard(),
                    parse_mode='HTML'
                )
            else:
                await update.message.reply_text(
                    f"❌ Failed to connect!\n\nError: {msg}\n\n"
                    f"Please check your email and App Password.\n\n"
                    f"<i>Get App Password from: myaccount.google.com/apppasswords</i>",
                    reply_markup=get_email_main_keyboard(),
                    parse_mode='HTML'
                )
            context.user_data.clear()
            return

    if context.user_data.get('monitor_action') == 'interval':
        try:
            interval = int(text)
            if interval < 1:
                interval = 1
            if interval > 1440:
                interval = 1440

            set_monitor_interval(interval)
            context.user_data['monitor_action'] = None

            await update.message.reply_text(
                f"✅ Monitoring interval set to {interval} minute(s)!",
                reply_markup=get_main_keyboard()
            )
        except ValueError:
            await update.message.reply_text("❌ Send a valid number (1-1440):")
            return MONITOR_INTERVAL
        return

    if context.user_data.get('monitor_action') == 'add':
        target = text
        target_id = None

        accounts = get_enabled_accounts()
        if accounts:
            client = await get_client(accounts[0][0])
            if client:
                result = await check_target_exists(client, target)
                await client.disconnect()

                if result.get('exists'):
                    target_id = str(result.get('id'))
                    target_name = result.get('username') or result.get('name') or target

        add_to_monitoring(target if not target_id else None, target_id or target)

        await update.message.reply_text(
            f"✅ <b>Added to monitoring!</b>\n\n"
            f"Target: <code>{target}</code>\n"
            f"Will be checked every {get_monitor_interval()} minute(s).\n\n"
            f"<i>You will be notified if it gets banned.</i>",
            reply_markup=get_main_keyboard(),
            parse_mode='HTML'
        )
        context.user_data['monitor_action'] = None
        return

    if context.user_data.get('setting_proxy'):
        acc_id = context.user_data.get('proxy_account_id')
        if acc_id:
            proxy = text if text.lower() != 'none' else None
            update_account_proxy(acc_id, proxy)
            await update.message.reply_text(
                f"✅ Proxy {'set' if proxy else 'removed'} for account!",
                reply_markup=get_main_keyboard()
            )
            context.user_data['setting_proxy'] = False
            context.user_data['proxy_account_id'] = None
        return

    if context.user_data.get('adding'):
        step = context.user_data.get('step')

        if step == 'api_id':
            try:
                context.user_data['api_id'] = int(text)
                context.user_data['step'] = 'api_hash'
                await update.message.reply_text(
                    "<b>🔑 Step 2/5 - Send API Hash:</b>\n\n"
                    "<i>Your API hash from my.telegram.org</i>",
                    parse_mode='HTML'
                )
                return ADD_API_HASH
            except:
                await update.message.reply_text("❌ Invalid API ID! Send number:")
                return ADD_API_ID

        elif step == 'api_hash':
            context.user_data['api_hash'] = text
            context.user_data['step'] = 'phone'
            await update.message.reply_text(
                "<b>📞 Step 3/5 - Send Phone Number:</b>\n\n"
                "<b>Format:</b> <code>+989123456789</code>\n"
                "<i>Include country code with +</i>",
                parse_mode='HTML'
            )
            return ADD_PHONE

        elif step == 'phone':
            context.user_data['phone'] = text
            await update.message.reply_text(
                "<b>🔒 Do you want to add a proxy?</b>\n\n"
                "<i>Proxy is optional - you can skip if not needed.</i>",
                reply_markup=get_proxy_choice_keyboard(),
                parse_mode='HTML'
            )
            return

        elif step == 'code':
            client = context.user_data.get('client')
            phone = context.user_data.get('phone')
            phone_code_hash = context.user_data.get('phone_code_hash')
            code = text.strip()

            try:
                await client.sign_in(phone, code, phone_code_hash=phone_code_hash)
                await client.disconnect()
                await update.message.reply_text(f"✅ Account {phone} added successfully!", reply_markup=get_main_keyboard())
                context.user_data.clear()
                return
            except errors.SessionPasswordNeededError:
                context.user_data['step'] = '2fa'
                await update.message.reply_text(
                    "<b>🔐 This account has 2FA enabled!</b>\n\n"
                    "Please send your 2FA password:",
                    parse_mode='HTML'
                )
                return ADD_2FA
            except errors.PhoneCodeInvalidError:
                await update.message.reply_text("❌ Invalid code! Please try again:")
                return ADD_CODE
            except errors.PhoneCodeExpiredError:
                await update.message.reply_text(
                    "❌ Code expired! Requesting new code...\n\n"
                    "Please wait a moment for the new code to arrive.",
                    parse_mode='HTML'
                )
                try:
                    result = await client.send_code_request(phone)
                    context.user_data['phone_code_hash'] = result.phone_code_hash
                    await update.message.reply_text(
                        "✅ New code sent! Please send the verification code:",
                        parse_mode='HTML'
                    )
                    return ADD_CODE
                except Exception as e:
                    await update.message.reply_text(f"❌ Error requesting new code: {str(e)[:100]}")
                    context.user_data.clear()
                    return
            except errors.FloodWaitError as e:
                await update.message.reply_text(f"⏳ Too many attempts! Please wait {e.seconds} seconds.")
                return ADD_CODE
            except Exception as e:
                await update.message.reply_text(f"❌ Error: {str(e)[:100]}")
                context.user_data.clear()
                return

        elif step == '2fa':
            client = context.user_data.get('client')
            phone = context.user_data.get('phone')
            password = text

            try:
                await client.sign_in(password=password)
                await client.disconnect()
                await update.message.reply_text(f"✅ Account {phone} added successfully with 2FA!", reply_markup=get_main_keyboard())
                context.user_data.clear()
                return
            except errors.PasswordHashInvalidError:
                await update.message.reply_text("❌ Wrong password! Please try again:")
                return ADD_2FA
            except errors.FloodWaitError as e:
                await update.message.reply_text(f"⏳ Too many attempts! Please wait {e.seconds} seconds.")
                return ADD_2FA
            except Exception as e:
                await update.message.reply_text(f"❌ Error: {str(e)[:100]}")
                context.user_data.clear()
                return
        return

    if context.user_data.get('add_proxy') == True:
        proxy = text if text.lower() != 'none' else None
        context.user_data['add_proxy'] = None

        api_id = context.user_data.get('api_id')
        api_hash = context.user_data.get('api_hash')
        phone = context.user_data.get('phone')

        add_account(api_id, api_hash, phone, proxy)
        await update.message.reply_text("🔄 Connecting to Telegram...")

        try:
            proxy_dict = parse_proxy_string(proxy) if proxy else None
            client = TelegramClient(f"sessions/{phone}", api_id, api_hash, proxy=proxy_dict)
            await client.connect()

            result = await client.send_code_request(phone)

            context.user_data['client'] = client
            context.user_data['step'] = 'code'
            context.user_data['phone'] = phone
            context.user_data['phone_code_hash'] = result.phone_code_hash

            await update.message.reply_text(
                "<b>📱 Verification code sent!</b>\n\n"
                "Please check your Telegram app and send the code:\n"
                "<i>(The code is usually 5 digits like 12345)</i>",
                parse_mode='HTML'
            )
            return ADD_CODE
        except errors.PhoneNumberBannedError:
            await update.message.reply_text("❌ This phone number is BANNED from Telegram!", reply_markup=get_main_keyboard())
            context.user_data.clear()
            return
        except errors.FloodWaitError as e:
            await update.message.reply_text(f"⏳ Too many attempts! Please wait {e.seconds} seconds.")
            context.user_data.clear()
            return
        except Exception as e:
            error_msg = str(e)
            if "proxy" in error_msg.lower():
                await update.message.reply_text(f"❌ Proxy error! Please check your proxy settings.\n\nError: {error_msg[:100]}", reply_markup=get_main_keyboard())
            else:
                await update.message.reply_text(f"❌ Error: {error_msg[:100]}", reply_markup=get_main_keyboard())
            context.user_data.clear()
            return

    elif context.user_data.get('action') == 'send':
        if 'send_target' not in context.user_data:
            target = text
            if extract_chat_from_link(text):
                target = extract_chat_from_link(text)
            context.user_data['send_target'] = target
            await update.message.reply_text(
                "<b>📝 Send your message:</b>\n\n"
                "<i>Type the message you want to send</i>",
                parse_mode='HTML'
            )
        elif 'send_message' not in context.user_data:
            context.user_data['send_message'] = text
            await update.message.reply_text(
                "<b>🔢 How many times to send?</b> (1-50):",
                parse_mode='HTML'
            )
        elif 'send_count' not in context.user_data:
            try:
                count = int(text)
                if count < 1:
                    await update.message.reply_text("❌ Minimum 1! Try again:")
                    return
                if count > 50:
                    count = 50
                    await update.message.reply_text("⚠️ Max 50, setting to 50.")
                await process_send_message(update, context, count)
            except:
                await update.message.reply_text("❌ Send a number!")

    elif context.user_data.get('action') == 'block':
        await process_block_action(update, context, text)

    elif context.user_data.get('action') == 'bulk':
        targets = [t.strip() for t in text.split('\n') if t.strip()]
        if targets:
            context.user_data['bulk_targets'] = targets
            context.user_data['action'] = 'bulk_category'
            await update.message.reply_text(
                "<b>📋 Select category for bulk report:</b>",
                reply_markup=get_level_1_keyboard(),
                parse_mode='HTML'
            )
        else:
            await update.message.reply_text("❌ No valid targets!")

    elif context.user_data.get('report_mode') == 'single' and 'report_category' not in context.user_data:
        target = text
        msg_id = 0

        username, extracted_msg_id = extract_from_link(text)
        if username and extracted_msg_id:
            target = username
            msg_id = extracted_msg_id
            target_name = f"@{username}"
        else:
            chat_username = extract_chat_from_link(text)
            if chat_username:
                target = chat_username
                target_name = f"@{chat_username}"
            else:
                target_name = target

        context.user_data['report_target'] = target
        context.user_data['msg_id'] = msg_id
        context.user_data['report_target_name'] = target_name

        await update.message.reply_text(
            "<b>📋 Select category:</b>",
            reply_markup=get_level_1_keyboard(),
            parse_mode='HTML'
        )

    elif context.user_data.get('report_mode') == 'multi_user':
        targets = extract_usernames_from_text(text)
        if targets:
            context.user_data['multi_targets'] = targets
            await update.message.reply_text(
                f"✅ <b>{len(targets)} targets detected!</b>\n\n"
                f"<b>Targets:</b>\n"
                + "\n".join([f"• <code>{t}</code>" for t in targets[:10]]) +
                (f"\n<i>... and {len(targets)-10} more</i>" if len(targets) > 10 else "") +
                f"\n\n📋 <b>Select category for all targets:</b>",
                reply_markup=get_level_1_keyboard(),
                parse_mode='HTML'
            )
        else:
            await update.message.reply_text("❌ No valid targets found! Send usernames or IDs one per line.")
            return REPORT_MULTI_USERS

    elif context.user_data.get('report_mode') == 'story':
        target = text
        chat_username = extract_chat_from_link(text)
        if chat_username:
            target = chat_username
            target_name = f"@{chat_username}"
        elif text.startswith('@'):
            target = text[1:]
            target_name = text
        else:
            target_name = target

        context.user_data['report_target'] = target
        context.user_data['report_target_name'] = target_name
        context.user_data['is_story'] = True

        await update.message.reply_text(
            "<b>📋 Select category for story report:</b>",
            reply_markup=get_level_1_keyboard(),
            parse_mode='HTML'
        )

    elif context.user_data.get('report_mode') == 'multi_message':
        links = [l.strip() for l in text.split('\n') if l.strip()]
        messages = []
        for link in links:
            username, msg_id = extract_from_link(link)
            if username and msg_id:
                messages.append({'target': username, 'msg_id': msg_id})

        if messages:
            context.user_data['multi_messages'] = messages
            await update.message.reply_text(
                f"✅ <b>{len(messages)} messages detected!</b>\n\n"
                f"📋 <b>Select category for all messages:</b>",
                reply_markup=get_level_1_keyboard(),
                parse_mode='HTML'
            )
        else:
            await update.message.reply_text("❌ No valid message links found! Send t.me/username/id links one per line.")
            return REPORT_MULTI_MESSAGE

    elif context.user_data.get('awaiting_comment'):
        context.user_data['report_comment'] = text
        context.user_data['awaiting_comment'] = False
        await update.message.reply_text(
            "<b>🔢 How many reports?</b> (1-50):",
            parse_mode='HTML'
        )
        return REPORT_COUNT

    elif 'report_category' in context.user_data and 'report_subcategory' in context.user_data and 'report_count' not in context.user_data:
        try:
            report_count = int(text)
            if report_count < 1:
                await update.message.reply_text("❌ Minimum 1 report! Try again:")
                return REPORT_COUNT
            if report_count > 50:
                report_count = 50
                await update.message.reply_text("⚠️ Maximum 50 reports, setting to 50.")

            context.user_data['report_count'] = report_count

            is_story = context.user_data.get('is_story', False)
            target_name = context.user_data.get('report_target_name', 'Unknown')
            msg_id = context.user_data.get('msg_id', 0)
            comment = context.user_data.get('report_comment', 'None')
            category = context.user_data.get('report_category')
            subcategory = context.user_data.get('report_subcategory')

            confirm_text = (
                f"<b>⚠️ CONFIRM REPORT</b>\n\n"
                f"🎯 Target: <code>{target_name}</code>\n"
                f"🆔 Msg ID: <code>{msg_id if msg_id else 'None'}</code>\n"
                f"📖 Story Report: <b>{'Yes' if is_story else 'No'}</b>\n"
                f"📂 {LEVEL_1_CATEGORIES.get(category, 'Unknown')}\n"
                f"📌 Reason: {subcategory}\n"
                f"💬 Comment: <i>{comment if comment != 'None' else 'None'}</i>\n"
                f"🔢 Reports: <b>{report_count}</b>\n\n"
                f"⚡ Ready to start?"
            )
            await update.message.reply_text(confirm_text, reply_markup=get_confirmation_keyboard(), parse_mode='HTML')

        except ValueError:
            await update.message.reply_text("❌ Send a number! (1-50):")
            return REPORT_COUNT

    elif context.user_data.get('email_target') is None and 'email_account_id' in context.user_data:
        target = text
        chat_username = extract_chat_from_link(text)
        if chat_username:
            target = chat_username
        elif text.startswith('@'):
            target = text[1:]

        context.user_data['email_target'] = target

        await update.message.reply_text(
            f"<b>📬 Select Recipient(s)</b>\n\n"
            f"Target: <code>{target}</code>\n\n"
            f"Choose where to send the report:",
            reply_markup=get_email_recipients_keyboard(),
            parse_mode='HTML'
        )
        return

    elif 'email_category' in context.user_data and 'email_recipients' in context.user_data and context.user_data.get('email_custom_body') is None and context.user_data.get('email_report_count') is None:
        try:
            count = int(text)
            if count < 1:
                count = 2
            if count > 10:
                count = 10
            context.user_data['email_report_count'] = count

            await execute_email_report(update, context)
        except ValueError:
            await update.message.reply_text("❌ Send a number (1-10):")
            return EMAIL_REPORT_COUNT

    elif context.user_data.get('email_custom_body') is not None and context.user_data.get('email_custom_body') == "":
        if text.upper() == "END":
            context.user_data['email_custom_body'] = context.user_data.get('email_temp_body', '')
            await update.message.reply_text(
                "<b>🔢 How many emails to send?</b>\n\n"
                "<i>Default is 2 per recipient per account.</i>\n"
                "Send a number (1-10):",
                parse_mode='HTML'
            )
            return EMAIL_REPORT_COUNT
        else:
            if 'email_temp_body' not in context.user_data:
                context.user_data['email_temp_body'] = ""
            context.user_data['email_temp_body'] += text + "\n"
            await update.message.reply_text(f"✏️ Body updated. Send <code>END</code> when finished.", parse_mode='HTML')
            return EMAIL_REPORT_CONFIRM

    elif update.message.document:
        file = await update.message.document.get_file()
        file_path = "import_temp.json"
        await file.download_to_drive(file_path)
        try:
            with open(file_path, 'r') as f:
                accounts = json.load(f)
            count = 0
            for acc in accounts:
                add_account(acc['api_id'], acc['api_hash'], acc['phone'], acc.get('proxy'))
                count += 1
            await update.message.reply_text(f"✅ Imported {count} accounts!", reply_markup=get_main_keyboard())
        except Exception as e:
            await update.message.reply_text(f"❌ Failed: {str(e)[:100]}")
        finally:
            os.remove(file_path)
async def process_send_message(update: Update, context: ContextTypes.DEFAULT_TYPE, count: int):
    target = context.user_data.get('send_target')
    message = context.user_data.get('send_message')
    account_id = context.user_data.get('account_id')
    use_all = context.user_data.get('all_accounts', False)

    if use_all:
        accounts = get_enabled_accounts()
        account_ids = [a[0] for a in accounts]
    else:
        account_ids = [account_id]

    await update.message.reply_text(f"✉️ Sending to <code>{target}</code>...", parse_mode='HTML')

    for aid in account_ids:
        client = await get_client(aid)
        if client:
            acc = get_account_by_id(aid)
            phone = acc[3] if acc else "Unknown"
            try:
                peer = await resolve_target(client, target)
                for i in range(count):
                    await client.send_message(peer, message)
                    await asyncio.sleep(random.uniform(1, 2))
                await client.disconnect()
                await update.message.reply_text(f"✅ {phone}: Sent {count} messages")
            except Exception as e:
                await update.message.reply_text(f"❌ {phone}: {str(e)[:50]}")

    await update.message.reply_text("✅ Done!", reply_markup=get_main_keyboard())
    context.user_data.clear()
async def process_block_action(update: Update, context: ContextTypes.DEFAULT_TYPE, target: str):
    account_id = context.user_data.get('account_id')
    use_all = context.user_data.get('all_accounts', False)

    if use_all:
        accounts = get_enabled_accounts()
        account_ids = [a[0] for a in accounts]
    else:
        account_ids = [account_id]

    await update.message.reply_text(f"🚫 Blocking <code>{target}</code>...", parse_mode='HTML')

    for aid in account_ids:
        client = await get_client(aid)
        if client:
            acc = get_account_by_id(aid)
            phone = acc[3] if acc else "Unknown"
            try:
                peer = await resolve_target(client, target)
                await client(BlockRequest(id=peer))
                await client.disconnect()
                await update.message.reply_text(f"✅ {phone}: Blocked {target}")
            except Exception as e:
                await update.message.reply_text(f"❌ {phone}: {str(e)[:50]}")

    await update.message.reply_text("✅ Done!", reply_markup=get_main_keyboard())
    context.user_data.clear()
async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE):
    context.user_data.clear()
    await update.message.reply_text("❌ Cancelled.", reply_markup=get_main_keyboard())
    return ConversationHandler.END
async def monitoring_worker_wrapper(context: ContextTypes.DEFAULT_TYPE):
    """Wrapper for monitoring worker"""
    await monitoring_worker(context)
def main():
    os.makedirs("sessions", exist_ok=True)

    app = Application.builder().token(BOT_TOKEN).build()

    if app.job_queue is None:
        print("⚠️ JobQueue not available! Monitoring will be disabled.")
        print("⚠️ Please install PTB with: pip install 'python-telegram-bot[job-queue]'")
    else:
        interval = get_monitor_interval()
        app.job_queue.run_repeating(monitoring_worker_wrapper, interval=interval * 60, first=10, name='monitoring')
        print(f"✅ Monitoring started with interval: {interval} minutes")

    telegram_conv_handler = ConversationHandler(
        entry_points=[CallbackQueryHandler(button_callback, pattern="^add_account$")],
        states={
            ADD_API_ID: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
            ADD_API_HASH: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
            ADD_PHONE: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
            ADD_CODE: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
            ADD_2FA: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
        },
        fallbacks=[CommandHandler("cancel", cancel)]
    )

    email_conv_handler = ConversationHandler(
        entry_points=[CallbackQueryHandler(button_callback, pattern="^add_email_account$")],
        states={
            ADD_EMAIL: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
            ADD_EMAIL_PASSWORD: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)],
        },
        fallbacks=[CommandHandler("cancel", cancel)]
    )

    app.add_handler(CommandHandler("start", start))
    app.add_handler(CommandHandler("cancel", cancel))
    app.add_handler(CallbackQueryHandler(button_callback))
    app.add_handler(telegram_conv_handler)
    app.add_handler(email_conv_handler)
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text))
    app.add_handler(MessageHandler(filters.Document.ALL, handle_text))

    print("=" * 60)
    print("🤖 REPORTER PRO BOT - ULTIMATE VERSION with EMAIL")
    print("=" * 60)
    print("✅ Telegram Report: YES")
    print("✅ Email Report: YES")
    print("✅ Proxy Support: YES")
    print("✅ Multi-User Report: YES")
    print("✅ Story Report: YES")
    print("✅ Multi-Message Report: YES")
    print("✅ Target Existence Check: YES")
    print("✅ Monitoring System: YES")
    print("✅ Attack Timer & Duration: YES")
    print("✅ Batch Reporting (1-50): YES")
    print("✅ Email Templates: YES")
    print("✅ Account Status Check: YES")
    print("=" * 60)

    app.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
    main()