import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { getAlgodClient, extractNetwork } from '../../../algorand-client.js';
import { withCommonParams } from '../../commonParams.js';
export const transactionTools = [
    {
        name: 'api_algod_get_pending_transaction',
        description: 'Get pending transaction information',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                txId: {
                    type: 'string',
                    description: 'Transaction ID'
                }
            },
            required: ['txId']
        })
    },
    {
        name: 'api_algod_get_pending_transactions_by_address',
        description: 'Get pending transactions for an address',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                address: {
                    type: 'string',
                    description: 'Account address'
                }
            },
            required: ['address']
        })
    },
    {
        name: 'api_algod_get_pending_transactions',
        description: 'Get all pending transactions',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                maxTxns: {
                    type: 'integer',
                    description: 'Maximum number of transactions to return'
                }
            }
        })
    },
    {
        name: 'api_algod_get_transaction_params',
        description: 'Get suggested transaction parameters',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {}
        })
    },
    {
        name: 'api_algod_get_node_status',
        description: 'Get current node status',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {}
        })
    },
    {
        name: 'api_algod_get_node_status_after_block',
        description: 'Get node status after a specific round',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                round: {
                    type: 'integer',
                    description: 'Round number'
                }
            },
            required: ['round']
        })
    }
];
export async function getPendingTransaction(txId, args) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error(`Fetching pending transaction info for ID ${txId}`);
        const response = await algodClient.pendingTransactionInformation(txId).do();
        console.error('Pending transaction response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Pending transaction fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get pending transaction: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function getPendingTransactionsByAddress(address, args) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error(`Fetching pending transactions for address ${address}`);
        const response = await algodClient.pendingTransactionByAddress(address).do();
        console.error('Pending transactions response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Pending transactions fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get pending transactions by address: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function getPendingTransactions(args, maxTxns) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error('Fetching all pending transactions');
        let search = algodClient.pendingTransactionsInformation();
        if (maxTxns !== undefined) {
            search = search.max(maxTxns);
        }
        const response = await search.do();
        console.error('Pending transactions response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Pending transactions fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get pending transactions: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function getTransactionParams(args) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error('Fetching transaction parameters');
        const response = await algodClient.getTransactionParams().do();
        console.error('Transaction parameters response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Transaction parameters fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get transaction params: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function getNodeStatus(args) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error('Fetching node status');
        const response = await algodClient.status().do();
        console.error('Node status response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Node status fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get status: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function getNodeStatusAfterBlock(round, args) {
    try {
        const network = extractNetwork(args);
        const algodClient = getAlgodClient(network);
        console.error(`Fetching node status after round ${round}`);
        const response = await algodClient.statusAfterBlock(round).do();
        console.error('Node status response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Node status fetch error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get status after block: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function handleTransactionTools(name, args) {
    switch (name) {
        case 'api_algod_get_pending_transaction': {
            const { txId } = args;
            const info = await getPendingTransaction(txId, args);
            return info;
        }
        case 'api_algod_get_pending_transactions_by_address': {
            const { address } = args;
            const info = await getPendingTransactionsByAddress(address, args);
            return info;
        }
        case 'api_algod_get_pending_transactions': {
            const { maxTxns } = args;
            const info = await getPendingTransactions(args, maxTxns);
            return info;
        }
        case 'api_algod_get_transaction_params': {
            const params = await getTransactionParams(args);
            return params;
        }
        case 'api_algod_get_node_status': {
            const nodeStatus = await getNodeStatus(args);
            return nodeStatus;
        }
        case 'api_algod_get_node_status_after_block': {
            const { round } = args;
            const nodeStatus = await getNodeStatusAfterBlock(round, args);
            return nodeStatus;
        }
        default:
            throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
    }
}
