import { CloseBotClient, ok, err } from "../client.js";
import type { ToolDefinition, ToolResult, LeadDto, LeadDtoPaginated, SearchQueryInput, LeadUpdateDto, InstanceUpdateDto } from "../types.js";

export const tools: ToolDefinition[] = [
  {
    name: "list_leads",
    description: "List leads with pagination, optionally filtered by source or lead ID",
    inputSchema: {
      type: "object",
      properties: {
        page: { type: "number", description: "Page number (0-indexed)" },
        pageSize: { type: "number", description: "Page size (default 20)" },
        sourceId: { type: "string", description: "Filter by source ID" },
        leadId: { type: "string", description: "Filter by lead ID" },
      },
    },
  },
  {
    name: "search_leads",
    description: "Search leads with advanced filters (source, channel, bot, persona, etc.)",
    inputSchema: {
      type: "object",
      properties: {
        search: { type: "string", description: "Search query string" },
        offset: { type: "number", description: "Result offset" },
        count: { type: "number", description: "Number of results" },
        sourceIds: { type: "array", items: { type: "string" }, description: "Filter by source IDs" },
        channels: { type: "array", items: { type: "string" }, description: "Filter by channels" },
        botIds: { type: "array", items: { type: "string" }, description: "Filter by bot IDs" },
        personaIds: { type: "array", items: { type: "string" }, description: "Filter by persona IDs" },
        minimumResponses: { type: "number", description: "Minimum number of responses" },
        lastMessageDirection: { type: "string", description: "Filter by last message direction (inbound/outbound)" },
        followUpScheduled: { type: "boolean", description: "Filter by follow-up scheduled status" },
      },
    },
  },
  {
    name: "get_lead",
    description: "Get detailed lead information by ID",
    inputSchema: {
      type: "object",
      properties: {
        leadId: { type: "string", description: "The lead ID" },
      },
      required: ["leadId"],
    },
  },
  {
    name: "update_lead_fields",
    description: "Update custom fields on a lead",
    inputSchema: {
      type: "object",
      properties: {
        leadId: { type: "string", description: "The lead ID" },
        fields: {
          type: "array",
          description: "Array of field updates",
          items: {
            type: "object",
            properties: {
              field: { type: "string", description: "Field name/key" },
              value: { type: "string", description: "Field value" },
            },
          },
        },
      },
      required: ["leadId", "fields"],
    },
  },
  {
    name: "delete_lead",
    description: "Delete a lead by ID",
    inputSchema: {
      type: "object",
      properties: {
        leadId: { type: "string", description: "The lead ID" },
      },
      required: ["leadId"],
    },
  },
  {
    name: "update_lead_instance",
    description: "Update a lead's bot instance (e.g., set follow-up time)",
    inputSchema: {
      type: "object",
      properties: {
        leadId: { type: "string", description: "The lead ID" },
        botId: { type: "string", description: "The bot ID" },
        followUpTime: { type: "string", description: "Follow-up time (ISO 8601 datetime)" },
      },
      required: ["leadId", "botId"],
    },
  },
];

export async function handler(
  client: CloseBotClient,
  name: string,
  args: Record<string, unknown>
): Promise<ToolResult> {
  try {
    switch (name) {
      case "list_leads":
        return ok(
          await client.get<LeadDtoPaginated>("/lead", {
            page: args.page,
            pageSize: args.pageSize,
            sourceId: args.sourceId,
            leadId: args.leadId,
          })
        );

      case "search_leads": {
        const body: SearchQueryInput = {
          search: args.search as string | undefined,
          offset: args.offset as number | undefined,
          count: args.count as number | undefined,
          sourceIds: args.sourceIds as string[] | undefined,
          channels: args.channels as string[] | undefined,
          botIds: args.botIds as string[] | undefined,
          personaIds: args.personaIds as string[] | undefined,
          minimumResponses: args.minimumResponses as number | undefined,
          lastMessageDirection: args.lastMessageDirection as string | undefined,
          followUpScheduled: args.followUpScheduled as boolean | undefined,
        };
        return ok(await client.post<LeadDto[]>("/lead/search", body));
      }

      case "get_lead":
        return ok(await client.get<LeadDto>(`/lead/${args.leadId}`));

      case "update_lead_fields": {
        const body: LeadUpdateDto = {
          fields: args.fields as Array<{ field?: string; value?: string }>,
        };
        return ok(await client.put(`/lead/${args.leadId}`, body));
      }

      case "delete_lead":
        return ok(await client.delete(`/lead/${args.leadId}`));

      case "update_lead_instance": {
        const body: InstanceUpdateDto = {};
        if (args.followUpTime !== undefined)
          body.followUpTime = args.followUpTime as string;
        return ok(
          await client.put(`/lead/${args.leadId}/instance/${args.botId}`, body)
        );
      }

      default:
        return err(`Unknown tool: ${name}`);
    }
  } catch (error) {
    return err(error);
  }
}
