import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { getIndexerClient, extractNetwork } from '../../../algorand-client.js';
import { ResponseProcessor } from '../../../utils/responseProcessor.js';
import { withCommonParams } from '../../commonParams.js';
export const accountTools = [
    {
        name: 'api_indexer_lookup_account_by_id',
        description: 'Get account information from indexer',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                address: {
                    type: 'string',
                    description: 'Account address'
                }
            },
            required: ['address']
        })
    },
    {
        name: 'api_indexer_lookup_account_assets',
        description: 'Get account assets',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                address: {
                    type: 'string',
                    description: 'Account address'
                },
                limit: {
                    type: 'integer',
                    description: 'Maximum number of assets to return'
                },
                assetId: {
                    type: 'integer',
                    description: 'Filter by asset ID'
                },
                nextToken: {
                    type: 'string',
                    description: 'Token for retrieving the next page of results'
                }
            },
            required: ['address']
        })
    },
    {
        name: 'api_indexer_lookup_account_app_local_states',
        description: 'Get account application local states',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                address: {
                    type: 'string',
                    description: 'Account address'
                }
            },
            required: ['address']
        })
    },
    {
        name: 'api_indexer_lookup_account_created_applications',
        description: 'Get applications created by this account',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                address: {
                    type: 'string',
                    description: 'Account address'
                }
            },
            required: ['address']
        })
    },
    {
        name: 'api_indexer_search_for_accounts',
        description: 'Search for accounts with various criteria',
        inputSchema: withCommonParams({
            type: 'object',
            properties: {
                limit: {
                    type: 'integer',
                    description: 'Maximum number of accounts to return'
                },
                assetId: {
                    type: 'integer',
                    description: 'Filter by asset ID'
                },
                applicationId: {
                    type: 'integer',
                    description: 'Filter by application ID'
                },
                currencyGreaterThan: {
                    type: 'integer',
                    description: 'Filter by minimum balance'
                },
                currencyLessThan: {
                    type: 'integer',
                    description: 'Filter by maximum balance'
                },
                nextToken: {
                    type: 'string',
                    description: 'Token for retrieving the next page of results'
                }
            }
        })
    }
];
export async function lookupAccountByID(address, network = 'mainnet') {
    try {
        const indexerClient = getIndexerClient(network);
        console.error(`Looking up account info for address ${address}`);
        const response = await indexerClient.lookupAccountByID(address).do();
        console.error('Account response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Account lookup error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get account info: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function lookupAccountAssets(address, params, network = 'mainnet') {
    try {
        const indexerClient = getIndexerClient(network);
        console.error(`Looking up assets for address ${address}`);
        let search = indexerClient.lookupAccountAssets(address);
        if (params?.limit) {
            search = search.limit(params.limit);
        }
        if (params?.assetId) {
            search = search.assetId(params.assetId);
        }
        if (params?.nextToken) {
            search = search.nextToken(params.nextToken);
        }
        const response = await search.do();
        console.error('Assets response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Assets lookup error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get account assets: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function lookupAccountAppLocalStates(address, network = 'mainnet') {
    try {
        const indexerClient = getIndexerClient(network);
        console.error(`Looking up app local states for address ${address}`);
        const response = await indexerClient.lookupAccountAppLocalStates(address).do();
        console.error('App local states response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('App local states lookup error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get account application local states: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function lookupAccountCreatedApplications(address, network = 'mainnet') {
    try {
        const indexerClient = getIndexerClient(network);
        console.error(`Looking up created applications for address ${address}`);
        const response = await indexerClient.lookupAccountCreatedApplications(address).do();
        console.error('Created applications response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Created applications lookup error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to get account created applications: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export async function searchAccounts(params, network = 'mainnet') {
    try {
        const indexerClient = getIndexerClient(network);
        console.error('Searching accounts with params:', params);
        let search = indexerClient.searchAccounts();
        if (params?.limit) {
            search = search.limit(params.limit);
        }
        if (params?.assetId) {
            search = search.assetID(params.assetId);
        }
        if (params?.applicationId) {
            search = search.applicationID(params.applicationId);
        }
        if (params?.currencyGreaterThan) {
            search = search.currencyGreaterThan(params.currencyGreaterThan);
        }
        if (params?.currencyLessThan) {
            search = search.currencyLessThan(params.currencyLessThan);
        }
        if (params?.nextToken) {
            search = search.nextToken(params.nextToken);
        }
        const response = await search.do();
        console.error('Search accounts response:', JSON.stringify(response, null, 2));
        return response;
    }
    catch (error) {
        console.error('Search accounts error:', error);
        if (error instanceof McpError) {
            throw error;
        }
        throw new McpError(ErrorCode.InternalError, `Failed to search accounts: ${error instanceof Error ? error.message : String(error)}`);
    }
}
export const handleAccountTools = ResponseProcessor.wrapResourceHandler(async function handleAccountTools(args) {
    const name = args.name;
    const network = extractNetwork(args);
    switch (name) {
        case 'api_indexer_lookup_account_by_id': {
            const { address } = args;
            const info = await lookupAccountByID(address, network);
            return info;
        }
        case 'api_indexer_lookup_account_app_local_states': {
            const { address } = args;
            const info = await lookupAccountAppLocalStates(address, network);
            return info;
        }
        case 'api_indexer_lookup_account_created_applications': {
            const { address } = args;
            const info = await lookupAccountCreatedApplications(address, network);
            return info.applications;
        }
        case 'api_indexer_search_for_accounts': {
            const info = await searchAccounts(args, network);
            return info.accounts;
        }
        case 'api_indexer_lookup_account_assets': {
            const { address, ...params } = args;
            const info = await lookupAccountAssets(address, params, network);
            return info.assets;
        }
        default:
            throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
    }
});
