// app/api/telegram/services/blockchain-checker.ts
import Web3 from 'web3';
import { TronWeb } from 'tronweb';
import { TransactionNetwork } from '@/lib/generated/prisma';

// BSC Configuration
const BSC_RPC = process.env.BSC_RPC || 'https://bsc-testnet-dataseed.bnbchain.org/';
const BSC_USDT_ADDRESS = process.env.BSC_USDT_ADDRESS || '0x337610d27c682e347c9cd60bd4b3b107c9d34ddd';
// TRON Configuration
const TRON_RPC = process.env.TRON_RPC || 'https://nile.trongrid.io/';
const TRON_USDT_ADDRESS = process.env.TRON_USDT_ADDRESS || 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf';




const USDT_ABI = [
    {
        "constant": true,
        "inputs": [],
        "name": "decimals",
        "outputs": [{ "name": "", "type": "uint8" }],
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            { "name": "_to", "type": "address" },
            { "name": "_value", "type": "uint256" }
        ],
        "name": "transfer",
        "outputs": [{ "name": "", "type": "bool" }],
        "type": "function"
    }
];



// Minimum confirmations
const MIN_CONFIRMATIONS = {
    TRC20: 1,
    BEP20: 3
};

export class BlockchainChecker {
    private web3: Web3;
    private tronWeb: any;
    private usdtContract: any;

    constructor() {
        this.web3 = new Web3(BSC_RPC);
        this.usdtContract = new this.web3.eth.Contract(USDT_ABI as any, BSC_USDT_ADDRESS);
        this.tronWeb = new TronWeb({
            fullHost: TRON_RPC
        });
    }

    // بررسی تراکنش BSC
    async checkBSCTransaction(txHash: string): Promise<{
        success: boolean;
        amount?: number;
        confirmations?: number;
        toAddress?: string;
        fromAddress?: string;
        error?: string;
    }> {
        try {
            // دریافت اطلاعات تراکنش
            const transaction = await this.web3.eth.getTransaction(txHash);
            if (!transaction) {
                return { success: false, error: 'Transaction not found' };
            }

            // دریافت رسید تراکنش
            const receipt = await this.web3.eth.getTransactionReceipt(txHash);
            if (!receipt) {
                return { success: false, error: 'Transaction not confirmed yet' };
            }

            // بررسی وضعیت تراکنش
            if (!receipt.status) {
                return { success: false, error: 'Transaction failed' };
            }

            // دریافت بلاک فعلی برای محاسبه تأییدیه‌ها
            const currentBlock = await this.web3.eth.getBlockNumber();
            const confirmations = Number(currentBlock) - Number(receipt.blockNumber);

            // بررسی تعداد تأییدیه‌ها
            if (confirmations < MIN_CONFIRMATIONS.BEP20) {
                return {
                    success: false,
                    confirmations,
                    error: `Waiting for confirmations (${confirmations}/${MIN_CONFIRMATIONS.BEP20})`
                };
            }

            // بررسی اینکه آیا تراکنش به کانترکت USDT است
            if (transaction.to?.toLowerCase() !== BSC_USDT_ADDRESS.toLowerCase()) {
                return { success: false, error: 'Not a USDT transaction' };
            }

            // دیکود کردن input data برای دریافت اطلاعات transfer
            const inputData = transaction.input;

            // بررسی method signature (transfer: 0xa9059cbb)
            if (!inputData.startsWith('0xa9059cbb')) {
                return { success: false, error: 'Not a transfer transaction' };
            }

            // استخراج آدرس مقصد و مقدار از input data
            const toAddress = '0x' + inputData.slice(34, 74);
            const amountHex = '0x' + inputData.slice(74, 138);

            // تبدیل مقدار به عدد (USDT در BSC دارای 18 دسیمال است)
            const amount = Number(this.web3.utils.fromWei(amountHex, 'ether'));

            return {
                success: true,
                amount,
                confirmations,
                toAddress,
                fromAddress: transaction.from
            };

        } catch (error: any) {
            console.error('BSC check error:', error);
            return { success: false, error: error.message };
        }
    }

    // بررسی تراکنش TRON
    async checkTRONTransaction(txHash: string): Promise<{
        success: boolean;
        amount?: number;
        confirmations?: number;
        toAddress?: string;
        fromAddress?: string;
        error?: string;
    }> {
        try {
            // دریافت اطلاعات تراکنش
            const transaction = await this.tronWeb.trx.getTransaction(txHash);
            if (!transaction || Object.keys(transaction).length === 0) {
                return { success: false, error: 'Transaction not found' };
            }

            // دریافت اطلاعات تفصیلی تراکنش
            const transactionInfo = await this.tronWeb.trx.getTransactionInfo(txHash);
            if (!transactionInfo.id) {
                return { success: false, error: 'Transaction not confirmed yet' };
            }

            // بررسی وضعیت
            const status = transaction.ret[0].contractRet;
            if (status !== 'SUCCESS') {
                return { success: false, error: 'Transaction failed' };
            }

            // دریافت بلاک فعلی
            const currentBlock = await this.tronWeb.trx.getCurrentBlock();
            const confirmations = currentBlock.block_header.raw_data.number - transactionInfo.blockNumber;

            // بررسی تعداد تأییدیه‌ها
            if (confirmations < MIN_CONFIRMATIONS.TRC20) {
                return {
                    success: false,
                    confirmations,
                    error: `Waiting for confirmations (${confirmations}/${MIN_CONFIRMATIONS.TRC20})`
                };
            }

            // بررسی contract و استخراج اطلاعات
            const contract = transaction.raw_data.contract[0];

            if (contract.type !== 'TriggerSmartContract') {
                return { success: false, error: 'Not a smart contract transaction' };
            }

            const contractAddress = this.tronWeb.address.fromHex(contract.parameter.value.contract_address);

            // بررسی آدرس کانترکت USDT
            if (contractAddress !== TRON_USDT_ADDRESS) {
                return { success: false, error: 'Not a USDT transaction' };
            }

            // دیکود parameter data
            const data = contract.parameter.value.data;

            // بررسی method signature برای transfer (a9059cbb)
            if (!data.startsWith('a9059cbb')) {
                return { success: false, error: 'Not a transfer transaction' };
            }

            // استخراج آدرس مقصد (32 بایت بعد از method signature)
            const toAddressHex = '41' + data.slice(32, 72);
            const toAddress = this.tronWeb.address.fromHex(toAddressHex);

            // استخراج مقدار (32 بایت بعدی)
            const amountHex = data.slice(72, 136);
            // USDT در TRON دارای 6 دسیمال است
            const amount = parseInt(amountHex, 16) / 1000000;

            // آدرس فرستنده
            const fromAddress = this.tronWeb.address.fromHex(contract.parameter.value.owner_address);

            return {
                success: true,
                amount,
                confirmations,
                toAddress,
                fromAddress
            };

        } catch (error: any) {
            console.error('TRON check error:', error);
            return { success: false, error: error.message };
        }
    }

    // متد اصلی برای بررسی تراکنش
    async checkTransaction(
        txHash: string,
        network: TransactionNetwork
    ): Promise<{
        success: boolean;
        amount?: number;
        confirmations?: number;
        toAddress?: string;
        fromAddress?: string;
        error?: string;
    }> {
        switch (network) {
            case 'BEP20':
                return this.checkBSCTransaction(txHash);
            case 'TRC20':
                return this.checkTRONTransaction(txHash);
            default:
                return { success: false, error: 'Unsupported network' };
        }
    }

    // متد کمکی برای تأیید آدرس مقصد
    isValidRecipient(toAddress: string, expectedAddress: string): boolean {
        return toAddress.toLowerCase() === expectedAddress.toLowerCase();
    }
}