import { tool } from 'ai';
import { z } from "zod";
import { queryBirdeye } from "./client.js";


const searchTokens = async ({
  keyword,
  verifyToken,
  offset = 0,
  limit = 20
}) => {
  limit = Math.min(limit, 20);

  const params = {
    keyword,
    chain: "solana",
    target: "token",
    sort_by: "liquidity",
    sort_type: "desc",
    offset,
    limit
  };

  if (verifyToken !== undefined) {
    params.verify_token = verifyToken.toString();
  }

  const response = await queryBirdeye("defi/v3/search", params);
  
  const filteredTokens = response.items
    .filter(item => item.type === "token") 
    .flatMap(item => 
      item.result
        .filter(token => token.network === "solana") 
        .map(({ decimals, ...rest }) => rest)
    );

  return filteredTokens.length > 0 ? filteredTokens.slice(0, 20) : [];
};


export const getSearchTokensTool = (userId, chatId,responseId,  dataStream) => tool({
  description: "Search for tokens using name or ticker with options to filter verified tokens and paginate. When a user asks about ticker on-chain data and doesn't provide the contract address, look up verified tokens, unless the user says it's a new token.",
  parameters: z.object({
    keyword: z.string().describe("name or ticker to search for tokens"),
    isVerified: z
      .boolean()
      .optional()
      .describe("Optional filter to return only verified tokens"),
    offset: z
      .number()
      .optional()
      .describe("Offset for pagination"),
    limit: z
      .number()
      .optional()
      .describe("Limit for the number of results (max: 20)")
  }),
  execute: async ({ keyword, isVerified, offset, limit }) => {
    try {
      console.log(`${userId} ${chatId} called searchTokens with keyword: ${keyword} | isVerified: ${isVerified} | offset: ${offset} | limit: ${limit}`);
      const verifyToken = isVerified !== undefined ? isVerified : true;
      const tokens = await searchTokens({ keyword, verifyToken, offset, limit });
      if (tokens) {
        tokens.forEach(token => {
          dataStream.writeMessageAnnotation({
            id: responseId,
            tool_type: 'chart',
            content: token.address.toString(),
          });
        });

      }
    return tokens;
    } catch (error) {
      console.error(`Error occurred while searching for tokens: ${error.message}`);
      return 'Failed to search for tokens.';
    }
  },
});