import re
import base58
import hashlib
from decimal import Decimal, ROUND_DOWN
from datetime import datetime, timedelta

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.constants import ParseMode
from telegram.ext import ContextTypes

# =========================================================
# پرمیوم ایموجی‌ها
# =========================================================
P_BUY = "5312361253610475399"
P_CARD = "5445353829304387411"
P_SUPPORT = "5789918778921850035"
P_ACCOUNT = "5296369303661067030"
P_HELP = "5444856076954520455"
P_CROWN = "5217822164362739968"

P_EYE = "5792131172410594168"
P_LINK = "5271604874419647061"
P_X = "4994791839895651680"
P_WARN = "4996823372311561500"
P_COIN = "6032713293049633080"
P_TRX = "5312361253610475399"
P_DIAMOND = "6032952342339395168"
P_MAIL = "5013050643519112149"
P_FIRE = "5424972470023104089"
P_PIN = "5397782960512444700"
P_PLUS = "5397916757333654639"
P_OK = "4997091399745668102"
P_LEAF = "5870778972857438051"
P_BACK = "5816717549487788887"


def pemoji(emoji_id: str, fallback: str) -> str:
    return f"<tg-emoji emoji-id='{emoji_id}'>{fallback}</tg-emoji>"


def make_btn(text: str, callback_data: str = None, emoji_id: str = None, style: str = "primary", url: str = None):
    kwargs = {}

    if callback_data:
        kwargs["callback_data"] = callback_data

    if url:
        kwargs["url"] = url

    if emoji_id:
        kwargs["api_kwargs"] = {
            "icon_custom_emoji_id": emoji_id,
            "style": style,
        }

    return InlineKeyboardButton(text=text, **kwargs)


class DepositManager:
    def __init__(
        self,
        *,
        owner_id: int,
        report_channel_id: int,
        tron_wallet_address: str,
        ton_wallet_address: str,
        request_timeout: int,
        http_session,
        tronscan_api_key: str,
        nobitex_api_key: str,
        get_user,
        change_balance,
        tron_hash_used,
        save_used_tron_hash,
        now_gregorian_str,
        format_money,
        format_username,
        logger,
        get_all_admin_ids,
        save_pending_ton_hash,
        get_pending_ton_hash,
        update_pending_ton_hash_status,
        save_ton_notification_message,
        get_ton_notification_messages,
        clear_ton_notification_messages,
        esc,
    ):
        self.owner_id = owner_id
        self.report_channel_id = report_channel_id
        self.tron_wallet_address = tron_wallet_address
        self.ton_wallet_address = ton_wallet_address
        self.request_timeout = request_timeout
        self.http = http_session
        self.tronscan_api_key = tronscan_api_key
        self.nobitex_api_key = nobitex_api_key
        self.get_user = get_user
        self.change_balance = change_balance
        self.tron_hash_used = tron_hash_used
        self.save_used_tron_hash = save_used_tron_hash
        self.now_gregorian_str = now_gregorian_str
        self.format_money = format_money
        self.format_username = format_username
        self.logger = logger
        self.get_all_admin_ids = get_all_admin_ids
        self.save_pending_ton_hash = save_pending_ton_hash
        self.get_pending_ton_hash = get_pending_ton_hash
        self.update_pending_ton_hash_status = update_pending_ton_hash_status
        self.save_ton_notification_message = save_ton_notification_message
        self.get_ton_notification_messages = get_ton_notification_messages
        self.clear_ton_notification_messages = clear_ton_notification_messages
        self.esc = esc

    def tron_hex_to_base58(self, hex_address: str) -> str:
        hex_address = str(hex_address or "").strip()

        if not hex_address:
            return ""

        if hex_address.startswith("41"):
            addr = bytes.fromhex(hex_address)

            checksum = hashlib.sha256(
                hashlib.sha256(addr).digest()
            ).digest()[:4]

            return base58.b58encode(addr + checksum).decode()

        return hex_address

    def extract_tron_hash(self, value: str) -> str:
        value = (value or "").strip()

        m = re.search(r"([a-fA-F0-9]{64})", value)
        if m:
            return m.group(1).lower()

        return ""

    def is_valid_tron_hash(self, value: str) -> bool:
        return bool(self.extract_tron_hash(value))

    def is_valid_ton_wallet(self, value: str) -> bool:
        value = (value or "").strip()
        patterns = [
            r"^(?:EQ|UQ|kQ|0Q)[A-Za-z0-9_-]{46}$",
            r"^-?1:[a-fA-F0-9]{64}$",
            r"^0:[a-fA-F0-9]{64}$",
        ]
        return any(re.fullmatch(p, value) for p in patterns)

    def is_valid_ton_hash(self, value: str) -> bool:
        value = (value or "").strip()

        if self.is_valid_ton_wallet(value):
            return False

        if re.fullmatch(r"[a-fA-F0-9]{64}", value):
            return True

        if re.fullmatch(r"[A-Za-z0-9+/_=-]{40,100}", value):
            return True

        return False

    def tron_submit_hash_inline(self):
        return InlineKeyboardMarkup([
            [
                make_btn(
                    "ارسال هش ترون",
                    callback_data="user_send_tron_hash",
                    emoji_id=P_LINK,
                    style="success"
                )
            ],
            [
                make_btn(
                    "بازگشت",
                    callback_data="deposit_back",
                    emoji_id=P_BACK,
                    style="danger"
                )
            ]
        ])

    def ton_submit_hash_inline(self):
        return InlineKeyboardMarkup([
            [
                make_btn(
                    "ارسال هش تون",
                    callback_data="user_send_ton_hash",
                    emoji_id=P_DIAMOND,
                    style="success"
                )
            ],
            [
                make_btn(
                    "بازگشت",
                    callback_data="deposit_back",
                    emoji_id=P_BACK,
                    style="danger"
                )
            ]
        ])

    def ton_review_inline(self, pending_id: int):
        return InlineKeyboardMarkup([
            [
                make_btn(
                    "تایید هش",
                    callback_data=f"ton_approve:{pending_id}",
                    emoji_id=P_OK,
                    style="success"
                ),
                make_btn(
                    "رد هش",
                    callback_data=f"ton_reject:{pending_id}",
                    emoji_id=P_X,
                    style="danger"
                ),
            ]
        ])

    def _same_date_as_today(self, dt_obj: datetime) -> bool:
        iran_tx_date = (dt_obj + timedelta(hours=3, minutes=30)).date()
        iran_today = (datetime.utcnow() + timedelta(hours=3, minutes=30)).date()
        return iran_tx_date == iran_today

    def get_tronscan_headers(self) -> dict:
        headers = {
            "Accept": "application/json",
            "User-Agent": "Mozilla/5.0",
        }

        if self.tronscan_api_key and not self.tronscan_api_key.startswith("PUT_YOUR_"):
            headers["TRON-PRO-API-KEY"] = self.tronscan_api_key

        return headers

    def get_trx_rate_toman_from_nobitex(self) -> int:
        fallback_rate = 25000

        try:
            url = "https://apiv2.nobitex.ir/market/stats"

            headers = {
                "Accept": "application/json",
                "User-Agent": "Mozilla/5.0",
            }

            if self.nobitex_api_key and not self.nobitex_api_key.startswith("PUT_YOUR_"):
                headers["Authorization"] = f"Token {self.nobitex_api_key}"

            res = self.http.get(url, headers=headers, timeout=self.request_timeout)
            res.raise_for_status()
            data = res.json()

            if str(data.get("status", "")).lower() != "ok":
                return fallback_rate

            stats = data.get("stats", {}) or {}
            pair = (
                stats.get("trx-rls")
                or stats.get("TRX-RLS")
                or stats.get("trx-irt")
                or stats.get("TRX-IRT")
            )

            if not pair:
                return fallback_rate

            latest = (
                pair.get("latest")
                or pair.get("lastTradePrice")
                or pair.get("dayClose")
                or pair.get("close")
                or pair.get("bestSell")
                or pair.get("bestBuy")
                or pair.get("mark")
            )

            if latest is None:
                return fallback_rate

            rate = int(Decimal(str(latest)).quantize(Decimal("1"), rounding=ROUND_DOWN))

            if rate > 100000:
                rate = int((Decimal(str(rate)) / Decimal("10")).quantize(Decimal("1"), rounding=ROUND_DOWN))

            return rate

        except Exception as e:
            self.logger.warning("nobitex trx rate failed, fallback used: %s", e)
            return fallback_rate

    def fetch_tron_transaction(self, tx_hash: str) -> dict:
        try:
            res = self.http.post(
                "https://api.trongrid.io/wallet/gettransactionbyid",
                json={"value": tx_hash},
                timeout=self.request_timeout,
            )

            res.raise_for_status()
            data = res.json()

            if data and isinstance(data, dict) and data.get("txID"):
                return data

        except Exception as e:
            self.logger.warning("trongrid failed: %s", e)

        try:
            res = self.http.get(
                "https://apilist.tronscanapi.com/api/transaction-info",
                params={"hash": tx_hash},
                headers=self.get_tronscan_headers(),
                timeout=self.request_timeout,
            )

            res.raise_for_status()
            data = res.json()

            if data and isinstance(data, dict) and data.get("hash"):
                return data

        except Exception as e:
            self.logger.warning("tronscan fallback failed: %s", e)

        raise ValueError("تراکنش پیدا نشد.")

    def verify_tron_transfer_to_wallet(self, tx_hash: str, target_wallet: str) -> dict:
        tx_data = self.fetch_tron_transaction(tx_hash)

        if not tx_data or not isinstance(tx_data, dict):
            raise ValueError("تراکنش پیدا نشد.")

        # حالت TronGrid
        if tx_data.get("txID"):
            contract_ret = str(
                tx_data.get("ret", [{}])[0].get("contractRet", "")
            ).upper()

            if contract_ret != "SUCCESS":
                raise ValueError("تراکنش موفق نبوده است.")

            contract = (
                tx_data.get("raw_data", {})
                .get("contract", [{}])[0]
                .get("parameter", {})
                .get("value", {})
            )

            to_address = self.tron_hex_to_base58(
                contract.get("to_address", "")
            )

            amount_sun = contract.get("amount")

            tx_ts = (
                tx_data.get("raw_data", {})
                .get("timestamp")
            )

        # حالت TronScan
        elif tx_data.get("hash"):
            confirmed = bool(tx_data.get("confirmed"))
            contract_ret = str(tx_data.get("contractRet", "")).upper()

            if not confirmed:
                raise ValueError("تراکنش هنوز تایید نشده است.")

            if contract_ret != "SUCCESS":
                raise ValueError("تراکنش موفق نبوده است.")

            to_address = str(tx_data.get("toAddress", "")).strip()

            contract_data = tx_data.get("contractData", {}) or {}
            amount_sun = contract_data.get("amount") or tx_data.get("amount")

            tx_ts = tx_data.get("timestamp")

        else:
            raise ValueError("تراکنش پیدا نشد.")

        if to_address != target_wallet:
            raise ValueError("این هش مربوط به آدرس ولت شما نیست.")

        if amount_sun is None:
            raise ValueError("مقدار تراکنش پیدا نشد.")

        trx_amount = (
            Decimal(str(amount_sun)) / Decimal("1000000")
        ).quantize(
            Decimal("0.000001"),
            rounding=ROUND_DOWN
        )

        if trx_amount <= 0:
            raise ValueError("مقدار TRX نامعتبر است.")

        tx_datetime = None
        tx_time_str = self.now_gregorian_str()

        if tx_ts:
            try:
                tx_datetime = datetime.fromtimestamp(int(tx_ts) / 1000)
                tx_time_str = tx_datetime.strftime("%Y/%m/%d %H:%M:%S")
            except Exception:
                tx_datetime = None

        if tx_datetime is None:
            raise ValueError("زمان تراکنش پیدا نشد.")

        return {
            "tx_hash": tx_hash.lower(),
            "trx_amount": trx_amount,
            "tx_time": tx_time_str,
            "tx_datetime": tx_datetime,
        }

    def format_trx_amount(self, value: Decimal) -> str:
        q = value.quantize(Decimal("0.000001"), rounding=ROUND_DOWN)
        s = format(q.normalize(), "f")

        if "." in s:
            s = s.rstrip("0").rstrip(".")

        return s or "0"

    async def show_tron_deposit_info(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        context.user_data.clear()
        context.user_data["flow"] = "user_tron_deposit"

        text = (
            f"{pemoji(P_COIN, '🪙')} <b>افزایش موجودی از طریق ترون</b>\n\n"
            f"{pemoji(P_PIN, '📌')} لطفاً مقدار TRX را به آدرس زیر ارسال کن:\n\n"
            f"<code>{self.esc(self.tron_wallet_address)}</code>\n\n"
            f"{pemoji(P_LINK, '🔗')} بعد از واریز، روی دکمه «ارسال هش ترون» بزن و هش تراکنش یا لینک تراکنش را بفرست.\n\n"
            f"{pemoji(P_FIRE, '🔥')} اگر هش معتبر باشد، مبلغ با نرخ لحظه‌ای TRX به تومان تبدیل و خودکار به موجودی شما اضافه می‌شود."
        )

        sent = await update.message.reply_text(
            text,
            parse_mode=ParseMode.HTML,
            reply_markup=self.tron_submit_hash_inline()
        )

        context.user_data["deposit_info_message_id"] = sent.message_id

    async def show_ton_deposit_info(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        context.user_data.clear()
        context.user_data["flow"] = "user_ton_deposit"

        text = (
            f"{pemoji(P_DIAMOND, '💎')} <b>افزایش موجودی از طریق تون</b>\n\n"
            f"{pemoji(P_PIN, '📌')} لطفاً مقدار TON را به آدرس زیر ارسال کن:\n\n"
            f"<code>{self.esc(self.ton_wallet_address)}</code>\n\n"
            f"{pemoji(P_LINK, '🔗')} بعد از واریز، روی دکمه «ارسال هش تون» بزن.\n\n"
            f"{pemoji(P_WARN, '⚠️')} هش شما برای مالک یا ادمین‌ها ارسال می‌شود و بعد از بررسی، نتیجه برای شما فرستاده می‌شود."
        )

        sent = await update.message.reply_text(
            text,
            parse_mode=ParseMode.HTML,
            reply_markup=self.ton_submit_hash_inline()
        )

        context.user_data["deposit_info_message_id"] = sent.message_id

    async def start_waiting_for_tron_hash(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        await query.answer()

        try:
            await query.message.delete()
        except Exception:
            pass

        context.user_data.clear()
        context.user_data["flow"] = "user_tron_hash_wait"

        sent = await query.message.reply_text(
            f"{pemoji(P_LINK, '🔗')} <b>لطفاً هش یا لینک تراکنش ترون خود را بفرستید.</b>",
            parse_mode=ParseMode.HTML
        )
        context.user_data["deposit_info_message_id"] = sent.message_id

    async def start_waiting_for_ton_hash(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        await query.answer()

        try:
            await query.message.delete()
        except Exception:
            pass

        context.user_data.clear()
        context.user_data["flow"] = "user_ton_hash_wait"

        sent = await query.message.reply_text(
            f"{pemoji(P_DIAMOND, '💎')} <b>لطفاً هش تراکنش تون خود را بفرستید.</b>",
            parse_mode=ParseMode.HTML
        )
        context.user_data["deposit_info_message_id"] = sent.message_id

    async def deposit_back_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE, home_keyboard):
        query = update.callback_query
        await query.answer()

        try:
            await query.message.delete()
        except Exception:
            pass

        context.user_data.clear()

        await query.message.reply_text(
            f"{pemoji(P_OK, '✅')} <b>منوی کاربر</b>",
            parse_mode=ParseMode.HTML,
            reply_markup=home_keyboard
        )

    async def delete_deposit_info_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        msg_id = context.user_data.get("deposit_info_message_id")

        if not msg_id:
            return

        chat_id = update.effective_chat.id if update.effective_chat else None

        if not chat_id:
            return

        try:
            await context.bot.delete_message(chat_id=chat_id, message_id=msg_id)
        except Exception:
            pass

    async def process_user_tron_hash(self, update: Update, context: ContextTypes.DEFAULT_TYPE, tx_hash: str, home_keyboard):
        user = update.effective_user
        db_user = self.get_user(user.id)


        if not db_user:
            await update.message.reply_text(
                f"{pemoji(P_X, '❌')} کاربر پیدا نشد.",
                parse_mode=ParseMode.HTML,
                reply_markup=home_keyboard
            )
            context.user_data.clear()
            return

        tx_hash = self.extract_tron_hash(tx_hash)

        if not tx_hash:
            await update.message.reply_text(
                f"{pemoji(P_X, '❌')} هش ترون نامعتبر است.",
                parse_mode=ParseMode.HTML,
                reply_markup=home_keyboard
            )
            context.user_data.clear()
            return

        tx_hash = tx_hash.lower()

        if self.tron_hash_used(tx_hash):
            await update.message.reply_text(
                f"{pemoji(P_WARN, '⚠️')} این هش قبلاً استفاده شده و قابل استفاده مجدد نیست.",
                parse_mode=ParseMode.HTML,
                reply_markup=home_keyboard
            )
            context.user_data.clear()
            return

        try:
            tx_info = self.verify_tron_transfer_to_wallet(tx_hash, self.tron_wallet_address)
            rate_toman = self.get_trx_rate_toman_from_nobitex()

            trx_amount: Decimal = tx_info["trx_amount"]
            charged_amount = int(
                (trx_amount * Decimal(rate_toman)).to_integral_value(rounding=ROUND_DOWN)
            )

            if charged_amount <= 0:
                await update.message.reply_text(
                    f"{pemoji(P_X, '❌')} مبلغ قابل شارژ از این تراکنش صفر است.",
                    parse_mode=ParseMode.HTML,
                    reply_markup=home_keyboard
                )
                context.user_data.clear()
                return

            self.save_used_tron_hash(
                tx_hash=tx_hash,
                user_id=user.id,
                trx_amount=self.format_trx_amount(trx_amount),
                rate_irt=rate_toman,
                charged_amount=charged_amount,
            )

            ok, new_balance = self.change_balance(
                user_id=user.id,
                amount=charged_amount,
                admin_id=self.owner_id,
                tx_type="tron_deposit",
                description=f"شارژ خودکار با هش ترون {tx_hash}"
            )

            if not ok:
                await update.message.reply_text(
                    f"{pemoji(P_X, '❌')} {self.esc(new_balance)}",
                    parse_mode=ParseMode.HTML,
                    reply_markup=home_keyboard
                )

                context.user_data.clear()
                return

            await self.delete_deposit_info_message(update, context)

            username = db_user["username"] if db_user["username"] else "ندارد"
            first_name = db_user["first_name"] if db_user["first_name"] else "کاربر"

            report_text = (
                f"{pemoji(P_PLUS, '➕')} <b>شارژ جدید از طریق ترون</b>\n\n"
                f"{pemoji(P_ACCOUNT, '🔒')} کاربر: <b>{self.esc(first_name)}</b>\n\n"
                f"{pemoji(P_PIN, '📌')} آیدی عددی: <b>{user.id}</b>\n\n"
                f"{pemoji(P_LINK, '🔗')} یوزرنیم: <b>{self.esc(username)}</b>\n\n"
                f"{pemoji(P_MAIL, '✉')} زمان تراکنش: <b>{self.esc(tx_info['tx_time'])}</b>\n\n"
                f"{pemoji(P_LINK, '🔗')} Hash:\n<code>{self.esc(tx_hash)}</code>\n\n"
                f"{pemoji(P_COIN, '🪙')} مقدار: <b>{self.format_trx_amount(trx_amount)}</b> TRX\n\n"
                f"{pemoji(P_TRX, '🪙')} نرخ هر TRX: <b>{self.format_money(rate_toman)}</b> تومان\n\n"
                f"{pemoji(P_FIRE, '🔥')} مبلغ شارژ شده: <b>{self.format_money(charged_amount)}</b> تومان"
            )

            try:
                await context.bot.send_message(
                    chat_id=self.report_channel_id,
                    text=report_text,
                    parse_mode=ParseMode.HTML
                )
            except Exception as e:
                self.logger.warning("tron charge report failed: %s", e)

            context.user_data.clear()

            await update.message.reply_text(
                f"{pemoji(P_OK, '✅')} <b>شارژ با موفقیت انجام شد.</b>\n\n"
                f"{pemoji(P_COIN, '🪙')} مقدار: <b>{self.format_trx_amount(trx_amount)}</b> TRX\n\n"
                f"{pemoji(P_TRX, '🪙')} نرخ هر TRX: <b>{self.format_money(rate_toman)}</b> تومان\n\n"
                f"{pemoji(P_PLUS, '➕')} مبلغ شارژ شده: <b>{self.format_money(charged_amount)}</b> تومان\n\n"
                f"{pemoji(P_CARD, '💳')} موجودی جدید: <b>{self.format_money(new_balance)}</b> تومان",
                parse_mode=ParseMode.HTML,
                reply_markup=home_keyboard
            )

        except Exception as e:
            self.logger.exception("tron hash process failed")
            context.user_data.clear()

            await update.message.reply_text(
                f"{pemoji(P_X, '❌')} <b>بررسی هش ناموفق بود.</b>\n\n"
                f"{pemoji(P_WARN, '⚠️')} <b>{self.esc(str(e))}</b>",
                parse_mode=ParseMode.HTML,
                reply_markup=home_keyboard
            )

    async def process_user_ton_hash(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        user = update.effective_user
        tx_hash = (update.message.text or "").strip()

        await self.delete_deposit_info_message(update, context)

        if not self.is_valid_ton_hash(tx_hash):
            await update.message.reply_text(
                f"{pemoji(P_X, '❌')} هش تون نامعتبر است.",
                parse_mode=ParseMode.HTML
            )
            return

        pending_id = self.save_pending_ton_hash(
            user_id=user.id,
            username=self.format_username(user.username),
            first_name=user.first_name or "کاربر",
            tx_hash=tx_hash,
        )

        review_text = (
            f"{pemoji(P_DIAMOND, '💎')} <b>درخواست بررسی هش تون</b>\n\n"
            f"{pemoji(P_PIN, '📌')} آیدی عددی: <b>{user.id}</b>\n\n"
            f"{pemoji(P_ACCOUNT, '🔒')} نام: <b>{self.esc(user.first_name or 'کاربر')}</b>\n\n"
            f"{pemoji(P_LINK, '🔗')} یوزرنیم: <b>{self.esc(self.format_username(user.username))}</b>\n\n"
            f"{pemoji(P_LINK, '🔗')} هش (قابل کپی):\n"
            f"<code>{self.esc(tx_hash)}</code>\n\n"
            f"{pemoji(P_MAIL, '✉')} شناسه درخواست: <b>{pending_id}</b>\n\n"
            f"{pemoji(P_WARN, '⚠️')} فقط هش تراکنش‌های امروز را تایید کنید."
        )

        try:
            sent = await context.bot.send_message(
                chat_id=self.report_channel_id,
                text=review_text,
                parse_mode=ParseMode.HTML,
            )
            self.save_ton_notification_message(
                pending_id,
                self.report_channel_id,
                sent.message_id
            )
        except Exception as e:
            self.logger.warning("send ton hash to report channel failed: %s", e)

        recipient_ids = self.get_all_admin_ids()

        for admin_id in recipient_ids:
            try:
                sent = await context.bot.send_message(
                    chat_id=admin_id,
                    text=review_text,
                    parse_mode=ParseMode.HTML,
                    reply_markup=self.ton_review_inline(pending_id),
                )
                self.save_ton_notification_message(
                    pending_id,
                    admin_id,
                    sent.message_id
                )
            except Exception as e:
                self.logger.warning("send ton hash to admin %s failed: %s", admin_id, e)

        context.user_data.clear()

        await update.message.reply_text(
            f"{pemoji(P_OK, '✅')} برای مالکان ربات یا ادمین‌ها ارسال شد، لطفاً منتظر بمانید.",
            parse_mode=ParseMode.HTML
        )

    async def handle_ton_review_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        await query.answer()

        user = query.from_user

        if not query.data or ":" not in query.data:
            return

        action, pending_id_str = query.data.split(":", 1)

        if not pending_id_str.isdigit():
            await query.answer("درخواست نامعتبر است.", show_alert=True)
            return

        pending_id = int(pending_id_str)
        row = self.get_pending_ton_hash(pending_id)

        if not row:
            await query.answer("درخواست پیدا نشد.", show_alert=True)
            return

        if row["status"] != "pending":
            await query.answer("این درخواست قبلاً بررسی شده.", show_alert=True)
            return

        new_status = "approved" if action == "ton_approve" else "rejected"

        self.update_pending_ton_hash_status(
            pending_id=pending_id,
            status=new_status,
            reviewed_by=user.id,
        )

        try:
            if new_status == "approved":
                await context.bot.send_message(
                    chat_id=row["user_id"],
                    text=(
                        f"{pemoji(P_OK, '✅')} <b>هش ارسالی شما تایید شد.</b>\n\n"
                        f"{pemoji(P_LINK, '🔗')} هش:\n"
                        f"<code>{self.esc(row['tx_hash'])}</code>\n\n"
                        f"{pemoji(P_WARN, '⚠️')} لطفاً منتظر شارژ توسط مدیریت بمانید."
                    ),
                    parse_mode=ParseMode.HTML,
                )
            else:
                await context.bot.send_message(
                    chat_id=row["user_id"],
                    text=(
                        f"{pemoji(P_X, '❌')} هش ارسالی شما رد شد.\n\n"
                        f"{pemoji(P_LINK, '🔗')} هش:\n"
                        f"<code>{self.esc(row['tx_hash'])}</code>"
                    ),
                    parse_mode=ParseMode.HTML,
                )
        except Exception as e:
            self.logger.warning("notify user for ton review failed: %s", e)

        messages = self.get_ton_notification_messages(pending_id)

        for item in messages:
            try:
                await context.bot.delete_message(
                    chat_id=item["target_chat_id"],
                    message_id=item["message_id"]
                )
            except Exception:
                pass

        self.clear_ton_notification_messages(pending_id)

        try:
            if new_status == "approved":
                await context.bot.send_message(
                    chat_id=user.id,
                    text=(
                        f"{pemoji(P_OK, '✅')} هش تایید شد.\n\n"
                        f"{pemoji(P_PLUS, '➕')} لطفاً از پنل مدیریت، افزایش موجودی کاربر را انجام دهید."
                    ),
                    parse_mode=ParseMode.HTML,
                )
            else:
                await context.bot.send_message(
                    chat_id=user.id,
                    text=(
                        f"{pemoji(P_OK, '✅')} هش رد شد و به کاربر اطلاع داده شد.\n\n"
                    ),
                    parse_mode=ParseMode.HTML,
                )
        except Exception:
            pass

        try:
            admin_username = self.format_username(user.username)

            result_text = (
                f"{pemoji(P_DIAMOND, '💎')} <b>نتیجه بررسی هش تون</b>\n\n"
                f"{pemoji(P_MAIL, '✉')} شناسه درخواست: <b>{pending_id}</b>\n\n"
                f"{pemoji(P_ACCOUNT, '🔒')} کاربر: <b>{self.esc(row['first_name'])}</b>\n\n"
                f"{pemoji(P_PIN, '📌')} آیدی عددی: <b>{row['user_id']}</b>\n\n"
                f"{pemoji(P_LINK, '🔗')} یوزرنیم: <b>{self.esc(row['username'])}</b>\n\n"
                f"{pemoji(P_LINK, '🔗')} هش:\n"
                f"<code>{self.esc(row['tx_hash'])}</code>\n\n"
                f"{pemoji(P_CROWN, '👑')} بررسی توسط: <b>{user.id}</b>\n"
                f"{pemoji(P_LINK, '🔗')} آیدی اصلی: <b>{self.esc(admin_username)}</b>\n\n"
                f"{pemoji(P_FIRE, '🔥')} نتیجه: <b>{'تایید شد' if new_status == 'approved' else 'رد شد'}</b>"
            )

            await context.bot.send_message(
                chat_id=self.report_channel_id,
                text=result_text,
                parse_mode=ParseMode.HTML
            )

        except Exception as e:
            self.logger.warning("send final ton review report failed: %s", e)
