/**
 * MCP SSE Server for Shopify
 *
 * Provides MCP tools for accessing Shopify orders and customers data
 * using Server-Sent Events (SSE) protocol for n8n integration.
 *
 * Authentication: Internal API keys from internal_api_keys table
 * Required parameter: shop_id (store ID from stores table)
 * Protocol: MCP over HTTP with SSE (2024-11-05)
 */

import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
import {
  requireInternalApiKey,
  createInternalApiKeyErrorResponse
} from '../_shared/internal-api-key-auth.ts';
import {
  fetchAllOrders,
  fetchOrder,
  fetchOrderByName,
  fetchCustomers,
  ShopifyOrder,
  ShopifyCustomer,
  ShopifyOrderFilters,
  ShopifyCustomerFilters
} from '../_shared/shopify-client.ts';
import {
  McpTool,
  LlmCustomer,
  LlmOrder,
  LlmProduct
} from '../_shared/mcp-types.ts';
import {
  validateParams,
  cleanResponseData
} from '../_shared/mcp-helpers.ts';
import {
  getStoreQdrantConfig,
  queryQdrantProducts,
  queryQdrantOrders,
  queryQdrantCustomers,
  queryQdrantCustomContent
} from '../_shared/mcp-qdrant-helpers.ts';
import {
  getAccessPolicyConfig,
  validateAccess,
  isSyncAllowed,
  isApiOnlyMode,
  getDataTypePolicy,
  createApiOnlyNotice
} from '../_shared/access-policy-helpers.ts';
import {
  fetchProducts as fetchShopifyProducts
} from '../_shared/shopify-client.ts';
import {
  JsonRpcRequest,
  createSseResponse,
  sendSseMessage,
  closeSseStream,
  parseJsonRpcRequest,
  createJsonRpcSuccess,
  createJsonRpcError,
  createInitializeResult,
  validateInitializeParams,
  validateToolCallParams,
  ToolCallParams,
  ToolCallResult,
  JsonRpcErrorCode
} from '../_shared/mcp-sse.ts';

// Initialize Supabase client
const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
const supabase = createClient(supabaseUrl, supabaseServiceKey);

const SERVER_NAME = 'mcp-shopify';
const SERVER_VERSION = '3.0.0';

// MCP Tool Definitions
const TOOLS: McpTool[] = [
  {
    name: 'shopify_get_products',
    description: 'Get products from a Shopify store with filtering. Returns product catalog with details like name, SKU, price, and status. Use this to search for products or browse the catalog. Limited to 20 results maximum.',
    inputSchema: {
      type: 'object',
      properties: {
        shop_id: {
          type: 'string',
          description: 'The UUID of the Shopify store from the stores table'
        },
        sku: {
          type: 'string',
          description: 'Filter by product SKU (exact match)'
        },
        name: {
          type: 'string',
          description: 'Filter by product name (partial match, case-insensitive)'
        },
        status: {
          type: 'string',
          description: 'Filter by product status (active, draft, archived)'
        },
        min_price: {
          type: 'number',
          description: 'Minimum price filter'
        },
        max_price: {
          type: 'number',
          description: 'Maximum price filter'
        },
        limit: {
          type: 'number',
          description: 'Number of products to return (default: 10, max: 20)'
        }
      },
      required: ['shop_id']
    }
  },
  {
    name: 'shopify_get_order',
    description: 'Get a specific order from a Shopify store by order ID or order name (e.g., "#1001"). Returns complete order details including customer info, items, status, and totals. Use this when a customer provides their order number.',
    inputSchema: {
      type: 'object',
      properties: {
        shop_id: {
          type: 'string',
          description: 'The UUID of the Shopify store from the stores table'
        },
        order_id: {
          type: 'number',
          description: 'The Shopify order ID (numeric)'
        },
        order_name: {
          type: 'string',
          description: 'The Shopify order name (e.g., "#1001", "1001")'
        }
      },
      required: ['shop_id']
    }
  },
  {
    name: 'shopify_list_orders',
    description: 'List orders from a Shopify store with filtering. At least one filter is REQUIRED (created_at_min, created_at_max, updated_at_min, updated_at_max, customer_email, or customer_name). Returns order details including customer info, items, status, and totals. Limited to 20 results maximum.',
    inputSchema: {
      type: 'object',
      properties: {
        shop_id: {
          type: 'string',
          description: 'The UUID of the Shopify store from the stores table'
        },
        created_at_min: {
          type: 'string',
          description: 'Filter orders created after this ISO 8601 datetime (e.g., 2025-01-01T00:00:00Z)'
        },
        created_at_max: {
          type: 'string',
          description: 'Filter orders created before this ISO 8601 datetime'
        },
        updated_at_min: {
          type: 'string',
          description: 'Filter orders updated after this ISO 8601 datetime'
        },
        updated_at_max: {
          type: 'string',
          description: 'Filter orders updated before this ISO 8601 datetime'
        },
        customer_email: {
          type: 'string',
          description: 'Filter by customer email address'
        },
        customer_name: {
          type: 'string',
          description: 'Filter by customer name'
        },
        status: {
          type: 'string',
          description: 'Filter by order status: any, open, closed, cancelled',
          enum: ['any', 'open', 'closed', 'cancelled']
        },
        limit: {
          type: 'number',
          description: 'Number of orders to return (default: 5, max: 20)'
        }
      },
      required: ['shop_id']
    }
  },
  {
    name: 'shopify_get_customer',
    description: 'Get a specific customer from a Shopify store by email address. Returns a single customer with contact info, order count, and total spent. Email parameter is REQUIRED.',
    inputSchema: {
      type: 'object',
      properties: {
        shop_id: {
          type: 'string',
          description: 'The UUID of the Shopify store from the stores table'
        },
        email: {
          type: 'string',
          description: 'The customer email address (required)'
        }
      },
      required: ['shop_id', 'email']
    }
  },
  {
    name: 'shopify_search_custom_content',
    description: 'Search custom knowledge base (uploaded PDFs and text entries) for relevant information using semantic search. Returns matching content with titles, excerpts, and relevance scores. Use this to find custom documentation, policies, FAQs, or any store-specific information that has been uploaded.',
    inputSchema: {
      type: 'object',
      properties: {
        shop_id: {
          type: 'string',
          description: 'The UUID of the Shopify store from the stores table'
        },
        query: {
          type: 'string',
          description: 'The search query to find relevant content'
        },
        limit: {
          type: 'number',
          description: 'Number of results to return (default: 5, max: 10)'
        }
      },
      required: ['shop_id', 'query']
    }
  }
];

/**
 * Convert Shopify customer to LLM-friendly format
 */
function formatCustomerForLlm(customer: ShopifyCustomer): LlmCustomer {
  return {
    id: customer.id.toString(),
    name: `${customer.first_name} ${customer.last_name}`.trim(),
    email: customer.email,
    phone: customer.phone || customer.default_address?.phone || undefined,
    ordersCount: customer.orders_count,
    totalSpent: `${customer.total_spent} ${customer.currency}`
  };
}

/**
 * Convert Shopify order to LLM-friendly format
 */
function formatOrderForLlm(order: ShopifyOrder): LlmOrder {
  return {
    id: order.id.toString(),
    orderNumber: order.name,
    customer: {
      name: `${order.customer.first_name} ${order.customer.last_name}`.trim(),
      email: order.customer.email,
      phone: order.customer.phone || order.billing_address?.phone || order.shipping_address?.phone || undefined
    },
    status: `${order.financial_status}/${order.fulfillment_status || 'unfulfilled'}`,
    total: order.current_total_price,
    currency: order.currency,
    items: order.line_items.map(item => ({
      name: item.title,
      quantity: item.quantity,
      price: item.price
    })),
    createdAt: order.created_at
  };
}

/**
 * Handle shopify_get_products tool
 */
async function handleGetProducts(args: Record<string, any>): Promise<ToolCallResult> {
  const { shop_id, sku, name, status, min_price, max_price, limit = 10 } = args;

  const actualLimit = Math.min(Math.max(1, limit), 20);

  // Check access policy
  const accessConfig = await getAccessPolicyConfig(shop_id);
  const accessError = validateAccess(accessConfig, 'products');
  if (accessError) {
    return accessError;
  }

  const policy = getDataTypePolicy(accessConfig!, 'products');

  try {
    // Handle api_only mode: Direct API call
    if (isApiOnlyMode(policy)) {
      console.log('[MCP Shopify] Using direct API access (api_only mode)');

      // Fetch from Shopify API directly
      const apiProducts = await fetchShopifyProducts(shop_id, actualLimit);

      let products = apiProducts;

      // Apply client-side filters
      if (sku) {
        products = products.filter((p: any) =>
          p.variants?.some((v: any) => v.sku === sku)
        );
      }

      if (name) {
        const nameLower = name.toLowerCase();
        products = products.filter((p: any) =>
          (p.title || '').toLowerCase().includes(nameLower)
        );
      }

      if (status) {
        products = products.filter((p: any) => p.status === status);
      }

      if (min_price !== undefined || max_price !== undefined) {
        products = products.filter((p: any) => {
          const price = parseFloat(p.variants?.[0]?.price || '0');
          if (min_price !== undefined && price < min_price) return false;
          if (max_price !== undefined && price > max_price) return false;
          return true;
        });
      }

      // Limit results
      products = products.slice(0, actualLimit);

      // Format for LLM
      const formattedProducts: LlmProduct[] = products.map((p: any) => ({
        id: p.id.toString(),
        name: p.title,
        sku: p.variants?.[0]?.sku || undefined,
        price: p.variants?.[0]?.price || undefined,
        currency: undefined,
        status: p.status || undefined,
        description: p.body_html || undefined,
        tags: p.tags || undefined
      }));

      const cleanedProducts = cleanResponseData(formattedProducts);

      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            count: products.length,
            limit: actualLimit,
            source: 'api_direct',
            access_mode: 'api_only',
            notice: createApiOnlyNotice('products'),
            products: cleanedProducts
          })
        }]
      };
    }

    // Handle sync mode: Use Qdrant or SQL cache
    if (isSyncAllowed(policy)) {
      const qdrantConfig = await getStoreQdrantConfig(shop_id);

      if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncProducts) {
        const products = await queryQdrantProducts(
          shop_id,
          qdrantConfig.shopname,
          { sku, name, status, minPrice: min_price, maxPrice: max_price },
          actualLimit
        );

        const cleanedProducts = cleanResponseData(products);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              count: products.length,
              limit: actualLimit,
              source: 'qdrant',
              access_mode: 'sync',
              products: cleanedProducts
            })
          }]
        };
      } else {
      let query = supabase
        .from('shopify_products_cache')
        .select('*')
        .eq('store_id', shop_id);

      if (sku) query = query.eq('sku', sku);
      if (status) query = query.eq('status', status);

      query = query.limit(actualLimit);

      const { data: cachedProducts, error: cacheError } = await query;

      if (cacheError) {
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ error: `Failed to fetch products: ${cacheError.message}` })
          }],
          isError: true
        };
      }

      let products = cachedProducts || [];

      if (name) {
        const nameLower = name.toLowerCase();
        products = products.filter((p: any) =>
          (p.title || '').toLowerCase().includes(nameLower)
        );
      }

      if (min_price !== undefined) {
        products = products.filter((p: any) => (parseFloat(p.price) || 0) >= min_price);
      }

      if (max_price !== undefined) {
        products = products.filter((p: any) => (parseFloat(p.price) || 0) <= max_price);
      }

      products = products.slice(0, actualLimit);

      const formattedProducts: LlmProduct[] = products.map((p: any) => ({
        id: p.shopify_product_id || p.id,
        name: p.title,
        sku: p.sku || undefined,
        price: p.price || undefined,
        currency: p.currency || undefined,
        status: p.status || undefined,
        description: p.description || undefined,
        tags: p.tags || undefined
      }));

      const cleanedProducts = cleanResponseData(formattedProducts);

      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            count: formattedProducts.length,
            limit: actualLimit,
            source: 'sql_cache',
            access_mode: 'sync',
            products: cleanedProducts
          })
        }]
      };
      }
    }

    // Fallback (should not reach here)
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({ error: 'Invalid access policy configuration' })
      }],
      isError: true
    };
  } catch (error) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({ error: `Failed to fetch products: ${error instanceof Error ? error.message : 'Unknown error'}` })
      }],
      isError: true
    };
  }
}

/**
 * Handle shopify_get_order tool
 */
async function handleGetOrder(args: Record<string, any>): Promise<ToolCallResult> {
  const { shop_id, order_id, order_name } = args;

  // Validate at least one identifier is provided
  if (!order_id && !order_name) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: 'Either order_id or order_name parameter is required'
        })
      }],
      isError: true
    };
  }

  // Check access policy
  const accessConfig = await getAccessPolicyConfig(shop_id);
  const accessError = validateAccess(accessConfig, 'orders');
  if (accessError) {
    return accessError;
  }

  const policy = getDataTypePolicy(accessConfig!, 'orders');

  try {
    let order: ShopifyOrder | null = null;

    // Try fetching by ID first
    if (order_id) {
      order = await fetchOrder(shop_id, order_id);
    }
    // Otherwise try by name
    else if (order_name) {
      // Normalize order name (add # if not present)
      const normalizedName = order_name.startsWith('#') ? order_name : `#${order_name}`;
      order = await fetchOrderByName(shop_id, normalizedName);
    }

    if (!order) {
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: `Order not found: ${order_id || order_name}`
          })
        }],
        isError: true
      };
    }

    // Format for LLM
    const formattedOrder = formatOrderForLlm(order);
    const cleanedOrder = cleanResponseData(formattedOrder);

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          access_mode: policy,
          notice: isApiOnlyMode(policy) ? createApiOnlyNotice('orders') : undefined,
          order: cleanedOrder
        })
      }]
    };
  } catch (error) {
    console.error('[MCP Shopify] Error fetching order:', error);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: `Failed to fetch order: ${error instanceof Error ? error.message : 'Unknown error'}`
        })
      }],
      isError: true
    };
  }
}

/**
 * Handle shopify_list_orders tool
 */
async function handleListOrders(args: Record<string, any>): Promise<ToolCallResult> {
  const {
    shop_id,
    created_at_min,
    created_at_max,
    updated_at_min,
    updated_at_max,
    customer_email,
    customer_name,
    status,
    limit = 5
  } = args;

  // Validate at least one filter is provided
  const hasFilter = created_at_min || created_at_max || updated_at_min || updated_at_max || customer_email || customer_name;
  if (!hasFilter) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: 'At least one filter is required: created_at_min, created_at_max, updated_at_min, updated_at_max, customer_email, or customer_name'
        })
      }],
      isError: true
    };
  }

  // Enforce limit constraints
  const actualLimit = Math.min(Math.max(1, limit), 20);

  // Check access policy
  const accessConfig = await getAccessPolicyConfig(shop_id);
  const accessError = validateAccess(accessConfig, 'orders');
  if (accessError) {
    return accessError;
  }

  const policy = getDataTypePolicy(accessConfig!, 'orders');

  try {
    // Build filters
    const filters: ShopifyOrderFilters = {};
    if (status) filters.status = status;
    if (customer_email) filters.email = customer_email;
    if (customer_name) filters.name = customer_name;
    if (created_at_min) filters.created_at_min = created_at_min;
    if (created_at_max) filters.created_at_max = created_at_max;
    if (updated_at_min) filters.updated_at_min = updated_at_min;
    if (updated_at_max) filters.updated_at_max = updated_at_max;

    // Fetch orders from Shopify API
    const allOrders = await fetchAllOrders(shop_id, filters);

    // Apply limit
    const limitedOrders = allOrders.slice(0, actualLimit);

    // Format for LLM
    const formattedOrders = limitedOrders.map(formatOrderForLlm);
    const cleanedOrders = cleanResponseData(formattedOrders);

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          count: formattedOrders.length,
          limit: actualLimit,
          total_available: allOrders.length,
          access_mode: policy,
          notice: isApiOnlyMode(policy) ? createApiOnlyNotice('orders') : undefined,
          filters_applied: {
            created_at_min,
            created_at_max,
            updated_at_min,
            updated_at_max,
            customer_email,
            customer_name,
            status
          },
          orders: cleanedOrders
        })
      }]
    };
  } catch (error) {
    console.error('[MCP Shopify] Error fetching orders:', error);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: `Failed to fetch orders: ${error instanceof Error ? error.message : 'Unknown error'}`
        })
      }],
      isError: true
    };
  }
}

/**
 * Handle shopify_get_customer tool (replaces list_customers)
 */
async function handleGetCustomer(args: Record<string, any>): Promise<ToolCallResult> {
  const { shop_id, email } = args;

  // Validate email is provided
  if (!email) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: 'Email parameter is required'
        })
      }],
      isError: true
    };
  }

  // Check access policy
  const accessConfig = await getAccessPolicyConfig(shop_id);
  const accessError = validateAccess(accessConfig, 'customers');
  if (accessError) {
    return accessError;
  }

  const policy = getDataTypePolicy(accessConfig!, 'customers');

  try {
    // Fetch customer by email from Shopify API
    const customers = await fetchCustomers(shop_id, 1, undefined, { email });

    if (customers.length === 0) {
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: `No customer found with email: ${email}`
          })
        }],
        isError: true
      };
    }

    // Return only the first customer
    const customer = formatCustomerForLlm(customers[0]);
    const cleanedCustomer = cleanResponseData(customer);

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          access_mode: policy,
          notice: isApiOnlyMode(policy) ? createApiOnlyNotice('customers') : undefined,
          customer: cleanedCustomer
        })
      }]
    };
  } catch (error) {
    console.error('[MCP Shopify] Error fetching customer:', error);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: `Failed to fetch customer: ${error instanceof Error ? error.message : 'Unknown error'}`
        })
      }],
      isError: true
    };
  }
}

/**
 * Handle custom content search
 */
async function handleSearchCustomContent(args: Record<string, any>): Promise<ToolCallResult> {
  const { shop_id, query, limit = 5 } = args;

  try {
    // Get store config for Qdrant connection
    const qdrantConfig = await getStoreQdrantConfig(shop_id);

    if (!qdrantConfig) {
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: 'Store configuration not found'
          })
        }],
        isError: true
      };
    }

    // Query custom content from Qdrant
    const results = await queryQdrantCustomContent(
      shop_id,
      qdrantConfig.shopname,
      query,
      Math.min(limit, 10) // Max 10 results
    );

    if (results.length === 0) {
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            message: 'No custom content found matching your query',
            results: []
          })
        }],
        isError: false
      };
    }

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          results: results.map(r => ({
            id: r.id,
            title: r.title,
            content_type: r.contentType,
            excerpt: r.excerpt,
            chunk_info: `Chunk ${r.chunkIndex + 1} of ${r.totalChunks}`,
            relevance_score: Math.round(r.relevanceScore * 100) / 100,
            original_filename: r.originalFilename,
            page_count: r.pageCount
          })),
          total: results.length
        })
      }],
      isError: false
    };
  } catch (error: any) {
    console.error('[MCP Shopify] Error searching custom content:', error);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({ error: `Failed to search custom content: ${error instanceof Error ? error.message : 'Unknown error'}` })
      }],
      isError: true
    };
  }
}

/**
 * Handle tool call
 */
async function handleToolCall(params: ToolCallParams): Promise<ToolCallResult> {
  const { name, arguments: args = {} } = params;

  // Validate shop_id is provided
  const validation = validateParams(args, ['shop_id']);
  if (!validation.valid) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: `Missing required parameters: ${validation.missing?.join(', ')}`
        })
      }],
      isError: true
    };
  }

  // Route to appropriate handler
  switch (name) {
    case 'shopify_get_products':
      return await handleGetProducts(args);

    case 'shopify_get_order':
      return await handleGetOrder(args);

    case 'shopify_list_orders':
      return await handleListOrders(args);

    case 'shopify_get_customer':
      const customerValidation = validateParams(args, ['shop_id', 'email']);
      if (!customerValidation.valid) {
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: `Missing required parameters: ${customerValidation.missing?.join(', ')}`
            })
          }],
          isError: true
        };
      }
      return await handleGetCustomer(args);

    case 'shopify_search_custom_content':
      const customContentValidation = validateParams(args, ['shop_id', 'query']);
      if (!customContentValidation.valid) {
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: `Missing required parameters: ${customContentValidation.missing?.join(', ')}`
            })
          }],
          isError: true
        };
      }
      return await handleSearchCustomContent(args);

    // Legacy tool names for backward compatibility
    case 'shopify_list_customers':
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: 'This tool has been removed. Use shopify_get_customer with email parameter instead.'
          })
        }],
        isError: true
      };

    case 'shopify_get_customer_orders':
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: 'This tool has been removed. Use shopify_list_orders with customer_email filter instead.'
          })
        }],
        isError: true
      };

    default:
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({ error: `Unknown tool: ${name}` })
        }],
        isError: true
      };
  }
}

/**
 * Main request handler with MCP SSE protocol
 */
serve(async (req: Request) => {
  // CORS preflight
  if (req.method === 'OPTIONS') {
    return new Response(null, {
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Authorization, Content-Type'
      }
    });
  }

  // MCP SSE endpoint - only POST requests
  if (req.method !== 'POST') {
    return new Response(JSON.stringify({ error: 'Method not allowed. Use POST.' }), {
      status: 405,
      headers: { 'Content-Type': 'application/json' }
    });
  }

  // Authenticate with internal API key
  const authResult = await requireInternalApiKey(req, supabase, 'read_orders');

  if (!authResult.valid) {
    return createInternalApiKeyErrorResponse(authResult);
  }

  // Create SSE response
  const { response, controller } = createSseResponse();

  // Parse JSON-RPC request
  let rpcRequest: JsonRpcRequest;
  try {
    rpcRequest = await parseJsonRpcRequest(req);
  } catch (error) {
    sendSseMessage(
      controller,
      createJsonRpcError(
        null,
        JsonRpcErrorCode.PARSE_ERROR,
        error instanceof Error ? error.message : 'Parse error'
      )
    );
    closeSseStream(controller);
    return response;
  }

  const { id, method, params } = rpcRequest;

  try {
    // Handle MCP methods
    switch (method) {
      case 'initialize':
        if (!validateInitializeParams(params)) {
          sendSseMessage(
            controller,
            createJsonRpcError(id!, JsonRpcErrorCode.INVALID_PARAMS, 'Invalid initialize parameters')
          );
          break;
        }

        const initResult = createInitializeResult(SERVER_NAME, SERVER_VERSION);
        sendSseMessage(controller, createJsonRpcSuccess(id!, initResult));
        break;

      case 'tools/list':
        sendSseMessage(controller, createJsonRpcSuccess(id!, { tools: TOOLS }));
        break;

      case 'tools/call':
        if (!validateToolCallParams(params)) {
          sendSseMessage(
            controller,
            createJsonRpcError(id!, JsonRpcErrorCode.INVALID_PARAMS, 'Invalid tool call parameters')
          );
          break;
        }

        const toolResult = await handleToolCall(params);
        sendSseMessage(controller, createJsonRpcSuccess(id!, toolResult));
        break;

      default:
        sendSseMessage(
          controller,
          createJsonRpcError(id!, JsonRpcErrorCode.METHOD_NOT_FOUND, `Method not found: ${method}`)
        );
    }
  } catch (error) {
    console.error('[MCP Shopify] Error handling request:', error);
    sendSseMessage(
      controller,
      createJsonRpcError(
        id!,
        JsonRpcErrorCode.INTERNAL_ERROR,
        error instanceof Error ? error.message : 'Internal error'
      )
    );
  }

  // Close stream
  closeSseStream(controller);
  return response;
});
