/**
 * ElevenLabs Voice Agent Tools Configuration
 *
 * Defines custom tools that the voice agent can use during conversations
 * to check availability, book appointments, and perform other actions.
 */

export interface VoiceAgentTool {
  name: string;
  description: string;
  type: "webhook" | "client" | "system";
  webhook_url?: string;
  parameters?: {
    type: "object";
    properties: Record<
      string,
      {
        type: string;
        description: string;
        format?: string;
        enum?: string[];
      }
    >;
    required?: string[];
  };
  wait_for_response?: boolean;
}

/**
 * Get the base URL for webhook endpoints
 */
function getBaseUrl(): string {
  return (
    process.env.NEXT_PUBLIC_BASE_URL ||
    process.env.NEXT_PUBLIC_APP_URL ||
    "http://localhost:9000"
  );
}

/**
 * Voice agent tools for appointment booking
 */
export const VOICE_AGENT_TOOLS: VoiceAgentTool[] = [
  {
    name: "check_availability",
    description:
      "Check available appointment slots for a specific date, service, and optionally a specific doctor. Call this when the user asks about available times or wants to book an appointment.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/n8n/availability`,
    parameters: {
      type: "object",
      properties: {
        date: {
          type: "string",
          format: "date",
          description:
            "The date to check availability for in YYYY-MM-DD format",
        },
        service: {
          type: "string",
          description:
            'The type of service or appointment (e.g., "dental checkup", "general consultation")',
        },
        doctor: {
          type: "string",
          description:
            "Optional specific doctor name to check availability for",
        },
        duration_minutes: {
          type: "number",
          description: "Desired appointment duration in minutes (default: 30)",
        },
      },
      required: ["date"],
    },
    wait_for_response: true,
  },
  {
    name: "create_booking",
    description:
      "Book an appointment after confirming all details with the caller. Only call this when the patient has confirmed the date, time, and service.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/bookings/voice`,
    parameters: {
      type: "object",
      properties: {
        date: {
          type: "string",
          format: "date",
          description: "Appointment date in YYYY-MM-DD format",
        },
        time: {
          type: "string",
          description: "Appointment time in HH:MM format (24-hour)",
        },
        service: {
          type: "string",
          description: "Type of service or appointment",
        },
        patient_name: {
          type: "string",
          description: "Full name of the patient",
        },
        patient_phone: {
          type: "string",
          description:
            "Patient phone number (will use caller number if not provided)",
        },
        patient_email: {
          type: "string",
          description: "Optional patient email for confirmation",
        },
        doctor: {
          type: "string",
          description: "Preferred doctor name (optional)",
        },
        notes: {
          type: "string",
          description: "Any special requests or notes from the patient",
        },
      },
      required: ["date", "time", "service", "patient_name"],
    },
    wait_for_response: true,
  },
  {
    name: "get_patient_appointments",
    description:
      "Retrieve upcoming appointments for a patient. Use the caller phone number to look up their appointments.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/appointments/by-phone`,
    parameters: {
      type: "object",
      properties: {
        phone_number: {
          type: "string",
          description: "Patient phone number to look up (use caller number)",
        },
        include_past: {
          type: "boolean",
          description: "Whether to include past appointments (default: false)",
        },
      },
      required: ["phone_number"],
    },
    wait_for_response: true,
  },
  {
    name: "cancel_appointment",
    description:
      "Cancel an existing appointment. Confirm the appointment details with the patient before cancelling.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/bookings/voice/cancel`,
    parameters: {
      type: "object",
      properties: {
        booking_id: {
          type: "string",
          description: "The booking ID to cancel",
        },
        phone_number: {
          type: "string",
          description: "Patient phone number for verification",
        },
        reason: {
          type: "string",
          description: "Reason for cancellation",
        },
      },
      required: ["booking_id", "phone_number"],
    },
    wait_for_response: true,
  },
  {
    name: "reschedule_appointment",
    description:
      "Reschedule an existing appointment to a new date and time. Confirm the new time slot is available before rescheduling.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/bookings/voice/reschedule`,
    parameters: {
      type: "object",
      properties: {
        booking_id: {
          type: "string",
          description: "The booking ID to reschedule",
        },
        new_date: {
          type: "string",
          format: "date",
          description: "New appointment date in YYYY-MM-DD format",
        },
        new_time: {
          type: "string",
          description: "New appointment time in HH:MM format (24-hour)",
        },
        phone_number: {
          type: "string",
          description: "Patient phone number for verification",
        },
      },
      required: ["booking_id", "new_date", "new_time", "phone_number"],
    },
    wait_for_response: true,
  },
  {
    name: "get_clinic_info",
    description:
      "Get information about the clinic such as address, hours, services offered, or general FAQ.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/n8n/kb/query`,
    parameters: {
      type: "object",
      properties: {
        query: {
          type: "string",
          description: "The question or topic to look up in the knowledge base",
        },
        category: {
          type: "string",
          enum: [
            "services",
            "doctors",
            "hours",
            "location",
            "pricing",
            "general",
          ],
          description: "Category of information to search",
        },
      },
      required: ["query"],
    },
    wait_for_response: true,
  },
  {
    name: "transfer_to_human",
    description:
      "Transfer the call to a human staff member. Use this when the patient requests to speak with a human, when the issue is too complex, or when sensitive topics arise.",
    type: "system",
    parameters: {
      type: "object",
      properties: {
        reason: {
          type: "string",
          description: "Reason for transferring to human",
        },
        department: {
          type: "string",
          enum: ["reception", "billing", "medical", "emergency"],
          description: "Department to transfer to",
        },
        summary: {
          type: "string",
          description:
            "Brief summary of the conversation to pass to the human agent",
        },
      },
      required: ["reason"],
    },
  },
  {
    name: "send_confirmation_sms",
    description:
      "Send an SMS confirmation to the patient with appointment details.",
    type: "webhook",
    webhook_url: `${getBaseUrl()}/api/notifications/voice/sms`,
    parameters: {
      type: "object",
      properties: {
        phone_number: {
          type: "string",
          description: "Phone number to send SMS to",
        },
        message_type: {
          type: "string",
          enum: ["booking_confirmation", "cancellation", "reminder"],
          description: "Type of message to send",
        },
        booking_id: {
          type: "string",
          description: "Booking ID for reference",
        },
      },
      required: ["phone_number", "message_type"],
    },
    wait_for_response: false,
  },
];

/**
 * Get tools configuration for ElevenLabs agent creation
 */
export function getAgentToolsConfig(): VoiceAgentTool[] {
  return VOICE_AGENT_TOOLS.map((tool) => ({
    ...tool,
    // Ensure webhook URLs have the current base URL
    webhook_url: tool.webhook_url?.replace(/^https?:\/\/[^/]+/, getBaseUrl()),
  }));
}

/**
 * Get a subset of tools based on enabled features
 */
export function getEnabledTools(options: {
  enableBooking?: boolean;
  enableKnowledgeBase?: boolean;
  enableTransfer?: boolean;
  enableSms?: boolean;
}): VoiceAgentTool[] {
  const {
    enableBooking = true,
    enableKnowledgeBase = true,
    enableTransfer = true,
    enableSms = false,
  } = options;

  return VOICE_AGENT_TOOLS.filter((tool) => {
    if (
      [
        "check_availability",
        "create_booking",
        "get_patient_appointments",
        "cancel_appointment",
        "reschedule_appointment",
      ].includes(tool.name)
    ) {
      return enableBooking;
    }
    if (tool.name === "get_clinic_info") {
      return enableKnowledgeBase;
    }
    if (tool.name === "transfer_to_human") {
      return enableTransfer;
    }
    if (tool.name === "send_confirmation_sms") {
      return enableSms;
    }
    return true;
  });
}
