"use client";

import { Calculator, Cog, Globe, type LucideIcon, PhoneForwarded, PhoneOff, Puzzle } from "lucide-react";
import { type ReactNode } from "react";

import type {
    CalculatorToolDefinition,
    ContextDestinationMappingConfig,
    ContextDestinationRoute,
    ContextDestinationRule,
    EndCallConfig,
    EndCallToolDefinition,
    HttpApiToolDefinition,
    McpToolDefinition,
    TransferCallConfig,
    TransferCallToolDefinition,
} from "@/client/types.gen";
import { createUuid } from "@/lib/uuid";

export type ToolCategory = "http_api" | "end_call" | "transfer_call" | "calculator" | "native" | "integration" | "mcp";

export type EndCallMessageType = "none" | "custom" | "audio";
export type TransferDestinationSource = "static" | "dynamic" | "context_mapping";

export interface ContextDestinationRouteRow extends ContextDestinationRoute {
    id: string;
}

export interface ContextDestinationRuleRow {
    id: string;
    context_path: string;
    routes: ContextDestinationRouteRow[];
}

export function createContextDestinationRouteRow(
    route?: Partial<ContextDestinationRoute>,
): ContextDestinationRouteRow {
    return {
        id: createUuid(),
        context_value: route?.context_value ?? "",
        destination: route?.destination ?? "",
    };
}

export function createContextDestinationRuleRow(
    rule?: Partial<ContextDestinationRule>,
): ContextDestinationRuleRow {
    return {
        id: createUuid(),
        context_path: rule?.context_path ?? "",
        routes: (rule?.routes ?? [{}]).map(createContextDestinationRouteRow),
    };
}

/** Normalize a stored mapping (ordered or legacy single-rule) into editable rows. */
export function contextMappingToRuleRows(
    mapping?: ContextDestinationMappingConfig | null,
): ContextDestinationRuleRow[] {
    if (!mapping) return [];
    const rules = mapping.rules?.length
        ? mapping.rules
        : mapping.context_path || mapping.routes?.length
            ? [{ context_path: mapping.context_path || "", routes: mapping.routes || [] }]
            : [];
    return rules.map(createContextDestinationRuleRow);
}

export function ruleRowsToContextMappingRules(
    rows: ContextDestinationRuleRow[],
): ContextDestinationRule[] {
    return rows.map((rule) => ({
        context_path: rule.context_path.trim(),
        routes: rule.routes.map((route) => ({
            context_value: route.context_value.trim(),
            destination: route.destination.trim(),
        })),
    }));
}

export interface ToolCategoryConfig {
    value: ToolCategory;
    label: string;
    description: string;
    icon: LucideIcon;
    iconName: string; // String name for storing in database
    iconColor: string;
    disabled?: boolean;
    autoFill?: {
        name: string;
        description: string;
    };
}

export const TOOL_CATEGORIES: ToolCategoryConfig[] = [
    {
        value: "http_api",
        label: "External HTTP API",
        description: "Make HTTP requests to external APIs",
        icon: Globe,
        iconName: "globe",
        iconColor: "#3B82F6",
    },
    {
        value: "end_call",
        label: "End Call",
        description: "End the call when conditions are met",
        icon: PhoneOff,
        iconName: "phone-off",
        iconColor: "#EF4444",
        autoFill: {
            name: "End Call",
            description: "End the call when either user asks to disconnect the call, or when you believe its time to end the conversation",
        },
    },
    {
        value: "transfer_call",
        label: "Transfer Call",
        description: "Transfer the call to another phone number (Twilio, Plivo)",
        icon: PhoneForwarded,
        iconName: "phone-forwarded",
        iconColor: "#10B981",
        autoFill: {
            name: "Transfer Call",
            description: "Transfer the caller to another phone number when requested",
        },
    },
    {
        value: "calculator",
        label: "Calculator",
        description: "Built-in calculator for arithmetic operations",
        icon: Calculator,
        iconName: "calculator",
        iconColor: "#F59E0B",
        autoFill: {
            name: "Calculator",
            description: "Perform arithmetic calculations (supports +, -, *, /, **, %, and parentheses)",
        },
    },
    {
        value: "mcp",
        label: "MCP Server",
        description: "Connect a customer MCP server; its tools become available to the agent",
        icon: Puzzle,
        iconName: "puzzle",
        iconColor: "#8B5CF6",
    },
    {
        value: "native",
        label: "Native (Coming Soon)",
        description: "Built-in tools like call transfer, DTMF input",
        icon: Cog,
        iconName: "cog",
        iconColor: "#6B7280",
        disabled: true,
    },
    {
        value: "integration",
        label: "Integration (Coming Soon)",
        description: "Third-party integrations like Google Calendar",
        icon: Puzzle,
        iconName: "puzzle",
        iconColor: "#8B5CF6",
        disabled: true,
    },
];

export function getCategoryConfig(category: ToolCategory): ToolCategoryConfig | undefined {
    return TOOL_CATEGORIES.find(c => c.value === category);
}

export function getToolIcon(category: string): LucideIcon {
    const config = TOOL_CATEGORIES.find(c => c.value === category);
    return config?.icon ?? Globe;
}

export function getToolIconColor(category: string, fallbackColor?: string): string {
    const config = TOOL_CATEGORIES.find(c => c.value === category);
    return config?.iconColor ?? fallbackColor ?? "#3B82F6";
}

export function renderToolIcon(category: string, className: string = "w-5 h-5 text-white"): ReactNode {
    const Icon = getToolIcon(category);
    return <Icon className={className} />;
}

export function getToolTypeLabel(category: string): string {
    switch (category) {
        case "end_call":
            return "End Call Tool";
        case "transfer_call":
            return "Transfer Call Tool";
        case "http_api":
            return "HTTP API Tool";
        case "calculator":
            return "Calculator Tool";
        case "native":
            return "Native Tool";
        case "integration":
            return "Integration Tool";
        case "mcp":
            return "MCP Server Tool";
        default:
            return "Tool";
    }
}

export const DEFAULT_END_CALL_REASON_DESCRIPTION =
    "The reason for ending the call (e.g., 'voicemail_detected', 'issue_resolved', 'customer_requested')";

export const DEFAULT_END_CALL_CONFIG: EndCallConfig = {
    messageType: "none",
    customMessage: "",
    endCallReason: false,
};

export const DEFAULT_TRANSFER_CALL_CONFIG: TransferCallConfig = {
    destination: "",
    messageType: "none",
    customMessage: "",
    timeout: 30,
};

export type ToolDefinition =
    | HttpApiToolDefinition
    | EndCallToolDefinition
    | TransferCallToolDefinition
    | CalculatorToolDefinition
    | McpToolDefinition;

export function createEndCallDefinition(config: EndCallConfig): EndCallToolDefinition {
    return {
        schema_version: 1,
        type: "end_call",
        config,
    };
}

export function createTransferCallDefinition(config: TransferCallConfig): TransferCallToolDefinition {
    return {
        schema_version: 1,
        type: "transfer_call",
        config,
    };
}

export function createHttpApiDefinition(): HttpApiToolDefinition {
    return {
        schema_version: 1,
        type: "http_api",
        config: {
            method: "POST",
            url: "",
        },
    };
}

export function createCalculatorDefinition(): CalculatorToolDefinition {
    return {
        schema_version: 1,
        type: "calculator",
    };
}

export const MCP_URL_PATTERN = /^https?:\/\//i;

export function createMcpDefinition(
    url: string,
    credentialUuid: string,
    toolsFilterCsv: string,
): McpToolDefinition {
    return {
        schema_version: 1,
        type: "mcp" as const,
        config: {
            transport: "streamable_http" as const,
            url: url.trim(),
            credential_uuid: credentialUuid || null,
            tools_filter: toolsFilterCsv
                .split(",")
                .map((s) => s.trim())
                .filter((s) => s.length > 0),
        },
    };
}

export function createToolDefinition(category: ToolCategory): ToolDefinition {
    switch (category) {
        case "end_call":
            return createEndCallDefinition(DEFAULT_END_CALL_CONFIG);
        case "transfer_call":
            return createTransferCallDefinition(DEFAULT_TRANSFER_CALL_CONFIG);
        case "calculator":
            return createCalculatorDefinition();
        case "http_api":
        default:
            return createHttpApiDefinition();
    }
}
