/**
 * MCP SSE Server for ShopRenter
 *
 * Provides MCP tools for accessing ShopRenter 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 {
  fetchOrders,
  fetchOrder,
  fetchCustomers,
  fetchProducts as fetchShopRenterProducts,
  ShopRenterOrder,
  ShopRenterCustomer,
  ShopRenterOrderFilters,
  ShopRenterCustomerFilters
} from '../_shared/shoprenter-client.ts';
import {
  McpTool,
  LlmCustomer,
  LlmOrder,
  LlmProduct
} from '../_shared/mcp-types.ts';
import {
  createMcpErrorResponse,
  createMcpSuccessResponse,
  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 {
  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-shoprenter';
const SERVER_VERSION = '3.0.0';

// MCP Tool Definitions
const TOOLS: McpTool[] = [
  {
    name: 'shoprenter_get_products',
    description: 'Get products from a ShopRenter 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 ShopRenter 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 (e.g., active, draft)'
        },
        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: 'shoprenter_get_order',
    description: 'Get a specific order from a ShopRenter store by customer-visible order number (innerId). 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 ShopRenter store from the stores table'
        },
        order_id: {
          type: 'string',
          description: 'The customer-visible order number (innerId), e.g., "172" - NOT the internal API ID'
        }
      },
      required: ['shop_id', 'order_id']
    }
  },
  {
    name: 'shoprenter_list_orders',
    description: 'List orders from a ShopRenter store with filtering. At least one filter is REQUIRED (createdAtMin, createdAtMax, updatedAtMin, updatedAtMax, or email). 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 ShopRenter store from the stores table'
        },
        createdAtMin: {
          type: 'string',
          description: 'Filter orders created after this ISO 8601 datetime (e.g., 2025-01-01T10:30:00)'
        },
        createdAtMax: {
          type: 'string',
          description: 'Filter orders created before this ISO 8601 datetime (e.g., 2025-01-01T10:30:00)'
        },
        updatedAtMin: {
          type: 'string',
          description: 'Filter orders updated after this ISO 8601 datetime (e.g., 2025-01-01T10:30:00)'
        },
        updatedAtMax: {
          type: 'string',
          description: 'Filter orders updated before this ISO 8601 datetime (e.g., 2025-01-01T10:30:00)'
        },
        email: {
          type: 'string',
          description: 'Filter by customer email address'
        },
        status: {
          type: 'string',
          description: 'Filter by order status: any, pending, processing, on-hold, completed, cancelled, refunded, failed'
        },
        limit: {
          type: 'number',
          description: 'Number of orders to return (default: 5, max: 20)'
        }
      },
      required: ['shop_id']
    }
  },
  {
    name: 'shoprenter_get_customer',
    description: 'Get a specific customer from a ShopRenter 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 ShopRenter store from the stores table'
        },
        email: {
          type: 'string',
          description: 'The customer email address (required)'
        }
      },
      required: ['shop_id', 'email']
    }
  },
  {
    name: 'shoprenter_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 ShopRenter 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 ShopRenter customer to LLM-friendly format
 */
function formatCustomerForLlm(customer: any): LlmCustomer {
  return {
    id: customer.id || customer.customer_id,
    name: `${customer.firstname || customer.first_name || ''} ${customer.lastname || customer.last_name || ''}`.trim(),
    email: customer.email,
    phone: customer.phone || undefined,
    ordersCount: customer.orders_count || undefined,
    totalSpent: customer.total_spent || undefined
  };
}

/**
 * Convert ShopRenter order to LLM-friendly format
 *
 * ShopRenter API returns orders from /orderExtend endpoint with this structure:
 * - firstname, lastname, email, phone (top-level fields)
 * - orderProducts[] array with product details
 * - orderTotals[] array with pricing breakdown
 * - shippingAddress1, shippingCity, etc.
 * - paymentAddress1, paymentCity, etc.
 *
 * We preserve the raw data and apply cleanResponseData to remove URLs/empty values
 */
function formatOrderForLlm(order: any): any {
  // ShopRenter orderExtend API returns the order data in a specific structure
  // We'll preserve most of the original structure but ensure key fields are present

  const formattedOrder: any = {
    id: order.id,
    orderNumber: order.innerId || order.orderNumber || order.id,

    // Customer details (top-level fields in ShopRenter API)
    firstname: order.firstname || '',
    lastname: order.lastname || '',
    email: order.email || '',
    phone: order.phone || '',

    // Order status and totals
    status: order.status || order.orderStatus,
    total: order.total || '0',
    currency: order.currency || {},

    // Shipping details
    shippingFirstname: order.shippingFirstname,
    shippingLastname: order.shippingLastname,
    shippingAddress1: order.shippingAddress1,
    shippingAddress2: order.shippingAddress2,
    shippingCity: order.shippingCity,
    shippingPostcode: order.shippingPostcode,
    shippingCountryName: order.shippingCountryName,
    shippingMethodName: order.shippingMethodName,

    // Payment details
    paymentFirstname: order.paymentFirstname,
    paymentLastname: order.paymentLastname,
    paymentAddress1: order.paymentAddress1,
    paymentAddress2: order.paymentAddress2,
    paymentCity: order.paymentCity,
    paymentPostcode: order.paymentPostcode,
    paymentCountryName: order.paymentCountryName,
    paymentMethodName: order.paymentMethodName,

    // Order items (orderProducts array)
    orderProducts: order.orderProducts || [],

    // Order totals breakdown
    orderTotals: order.orderTotals || [],

    // Additional fields
    comment: order.comment,
    dateCreated: order.dateCreated || order.created_at,
    dateUpdated: order.dateUpdated || order.updated_at,

    // Language and other metadata
    language: order.language,

    // Coupon info
    coupon: order.coupon,

    // Shipping mode
    shippingMode: order.shippingMode
  };

  // Remove undefined values (cleanResponseData will handle empty strings, empty arrays, etc.)
  Object.keys(formattedOrder).forEach(key => {
    if (formattedOrder[key] === undefined) {
      delete formattedOrder[key];
    }
  });

  return formattedOrder;
}

/**
 * Handle shoprenter_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;

  console.log('[MCP ShopRenter] handleGetProducts called with:', { shop_id, sku, name, status, min_price, max_price, limit });

  // 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, 'products');
  if (accessError) {
    return accessError;
  }

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

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

      // Fetch from ShopRenter API directly
      const apiProducts = await fetchShopRenterProducts(shop_id, 0, actualLimit);
      let products = Array.isArray(apiProducts) ? apiProducts : (apiProducts.items || apiProducts.data || []);

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

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

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

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

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

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

      // Format for LLM
      const formattedProducts: LlmProduct[] = products.map((p: any) => ({
        id: p.id || p.product_id,
        name: p.name || p.title,
        sku: p.sku || undefined,
        price: p.price ? p.price.toString() : 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: 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)) {
      // Check if Qdrant is enabled for this store
      const qdrantConfig = await getStoreQdrantConfig(shop_id);

      if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncProducts) {
        console.log('[MCP ShopRenter] Using Qdrant for products');

        // Query from Qdrant
        const products = await queryQdrantProducts(
          shop_id,
          qdrantConfig.shopname,
          { sku, name, status, minPrice: min_price, maxPrice: max_price },
          actualLimit
        );

        // Clean response data
        const cleanedProducts = cleanResponseData(products);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              count: products.length,
              limit: actualLimit,
              source: 'qdrant',
              access_mode: 'sync',
              products: cleanedProducts
            })
          }]
        };
      } else {
        console.log('[MCP ShopRenter] Qdrant not enabled, using SQL cache');

      // Fallback: Query from SQL cache (shoprenter_products_cache)
      let query = supabase
        .from('shoprenter_products_cache')
        .select('product_data')
        .eq('store_id', shop_id);

      // Apply filters (limited by JSONB querying)
      if (sku) {
        query = query.eq('product_data->>sku', sku);
      }

      if (status) {
        query = query.eq('product_data->>status', status);
      }

      query = query.limit(actualLimit);

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

      if (cacheError) {
        console.error('[MCP ShopRenter] Error querying SQL cache:', cacheError);
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: `Failed to fetch products from cache: ${cacheError.message}`
            })
          }],
          isError: true
        };
      }

      // Extract product data
      let products = (cachedProducts || []).map((p: any) => p.product_data);

      // Apply client-side filters
      if (name) {
        const nameLower = name.toLowerCase();
        products = products.filter((p: any) =>
          (p.name || p.title || '').toLowerCase().includes(nameLower)
        );
      }

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

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

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

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

        // Clean response data
        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) {
    console.error('[MCP ShopRenter] Error fetching products:', error);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: `Failed to fetch products: ${error instanceof Error ? error.message : 'Unknown error'}`
        })
      }],
      isError: true
    };
  }
}

/**
 * Fetch all orders with pagination (for filtering by customer name)
 */
async function fetchAllOrdersPages(
  shop_id: string,
  maxPages: number = 10,
  filters?: ShopRenterOrderFilters
): Promise<any[]> {
  const allOrders: any[] = [];
  let page = 0;  // ShopRenter API uses zero-based pagination
  let hasMore = true;

  while (hasMore && page < maxPages) {
    const response = await fetchOrders(shop_id, page, 100, filters);
    const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);

    if (orders.length === 0) {
      hasMore = false;
    } else {
      allOrders.push(...orders);
      hasMore = orders.length === 100;
      page++;
    }
  }

  return allOrders;
}

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

  console.log('[MCP ShopRenter] handleGetOrder called with:', { shop_id, order_id });

  // Validate order_id is provided
  if (!order_id) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: 'order_id 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 {
    // Handle api_only mode OR sync mode without Qdrant: Use direct API
    if (isApiOnlyMode(policy) || !isSyncAllowed(policy)) {
      console.log('[MCP ShopRenter] Using direct API access');

      // Search for order by innerId (customer-visible order number)
      console.log('[MCP ShopRenter] Fetching order with innerId:', order_id);
      const response = await fetchOrders(shop_id, 0, 1, { innerId: order_id });

      const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);

      console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });

      if (orders.length === 0) {
        console.warn('[MCP ShopRenter] No order found with innerId:', order_id);
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: `No order found with order number: ${order_id}`
            })
          }],
          isError: true
        };
      }

      console.log('[MCP ShopRenter] Order found:', { innerId: orders[0].innerId || orders[0].id });

      // Format for LLM
      const formattedOrder = formatOrderForLlm(orders[0]);

      // Clean response data
      const cleanedOrder = cleanResponseData(formattedOrder);

      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            source: isApiOnlyMode(policy) ? 'api_direct' : 'api',
            access_mode: policy,
            notice: isApiOnlyMode(policy) ? createApiOnlyNotice('orders') : undefined,
            order: cleanedOrder
          })
        }]
      };
    }

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

      if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
        console.log('[MCP ShopRenter] Using Qdrant for order lookup');

        // Query from Qdrant - scroll through orders to find matching order_id
        const orders = await queryQdrantOrders(
          shop_id,
          qdrantConfig.shopname,
          {},
          100  // Get more to search through
        );

        // Find order by innerId (order number)
        const order = orders.find((o: any) =>
          o.orderNumber === order_id || o.id === order_id
        );

        if (!order) {
          return {
            content: [{
              type: 'text',
              text: JSON.stringify({
                error: `No order found with order number: ${order_id}`
              })
            }],
            isError: true
          };
        }

        // Clean response data
        const cleanedOrder = cleanResponseData(order);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              source: 'qdrant',
              access_mode: 'sync',
              order: cleanedOrder
            })
          }]
        };
      } else {
        console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');

        // Search for order by innerId (customer-visible order number)
        console.log('[MCP ShopRenter] Fetching order with innerId:', order_id);
        const response = await fetchOrders(shop_id, 0, 1, { innerId: order_id });

        const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);

        console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });

        if (orders.length === 0) {
          console.warn('[MCP ShopRenter] No order found with innerId:', order_id);
          return {
            content: [{
              type: 'text',
              text: JSON.stringify({
                error: `No order found with order number: ${order_id}`
              })
            }],
            isError: true
          };
        }

        console.log('[MCP ShopRenter] Order found:', { innerId: orders[0].innerId || orders[0].id });

        // Format for LLM
        const formattedOrder = formatOrderForLlm(orders[0]);

        // Clean response data
        const cleanedOrder = cleanResponseData(formattedOrder);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              source: 'api',
              access_mode: 'sync',
              order: cleanedOrder
            })
          }]
        };
      }
    }

    // Fallback (should not reach here)
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({ error: 'Invalid access policy configuration' })
      }],
      isError: true
    };
  } catch (error) {
    console.error('[MCP ShopRenter] 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 shoprenter_list_orders tool
 */
async function handleListOrders(args: Record<string, any>): Promise<ToolCallResult> {
  const {
    shop_id,
    createdAtMin,
    createdAtMax,
    updatedAtMin,
    updatedAtMax,
    email,
    status,
    limit = 5
  } = args;

  console.log('[MCP ShopRenter] handleListOrders called with:', { shop_id, email, status, limit });

  // Validate at least one filter is provided
  const hasFilter = createdAtMin || createdAtMax || updatedAtMin || updatedAtMax || email;
  if (!hasFilter) {
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          error: 'At least one filter is required: createdAtMin, createdAtMax, updatedAtMin, updatedAtMax, or email'
        })
      }],
      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 {
    // Handle api_only mode: Direct API call
    if (isApiOnlyMode(policy)) {
      console.log('[MCP ShopRenter] Using direct API access (api_only mode)');

      // Build filters using correct parameter names
      const filters: ShopRenterOrderFilters = {};
      if (status) filters.status = status;
      if (email) filters.email = email;
      if (createdAtMin) filters.createdAtMin = createdAtMin;
      if (createdAtMax) filters.createdAtMax = createdAtMax;
      if (updatedAtMin) filters.updatedAtMin = updatedAtMin;
      if (updatedAtMax) filters.updatedAtMax = updatedAtMax;

      // Fetch orders from ShopRenter API
      const response = await fetchOrders(shop_id, 0, actualLimit, filters);
      const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);

      console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });

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

      // Format for LLM (now preserves all ShopRenter fields)
      const formattedOrders = limitedOrders.map(formatOrderForLlm);

      // Clean response data (removes URLs, empty values)
      const cleanedOrders = cleanResponseData(formattedOrders);

      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            count: formattedOrders.length,
            limit: actualLimit,
            source: 'api_direct',
            access_mode: 'api_only',
            notice: createApiOnlyNotice('orders'),
            filters_applied: {
              createdAtMin,
              createdAtMax,
              updatedAtMin,
              updatedAtMax,
              email,
              status
            },
            orders: cleanedOrders
          })
        }]
      };
    }

    // Handle sync mode: Use Qdrant or SQL cache
    if (isSyncAllowed(policy)) {
      // Check if Qdrant is enabled for this store
      const qdrantConfig = await getStoreQdrantConfig(shop_id);

      if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
        console.log('[MCP ShopRenter] Using Qdrant for orders');

        // Query from Qdrant with filters
        const qdrantOrders = await queryQdrantOrders(
          shop_id,
          qdrantConfig.shopname,
          { email, status },
          actualLimit
        );

        // Apply date filters client-side if provided
        let filteredOrders = qdrantOrders;

        if (createdAtMin) {
          const minDate = new Date(createdAtMin);
          filteredOrders = filteredOrders.filter((o: any) => {
            const created = new Date(o.dateCreated || o.createdAt || 0);
            return created >= minDate;
          });
        }

        if (createdAtMax) {
          const maxDate = new Date(createdAtMax);
          filteredOrders = filteredOrders.filter((o: any) => {
            const created = new Date(o.dateCreated || o.createdAt || 0);
            return created <= maxDate;
          });
        }

        if (updatedAtMin) {
          const minDate = new Date(updatedAtMin);
          filteredOrders = filteredOrders.filter((o: any) => {
            const updated = new Date(o.dateUpdated || o.updatedAt || 0);
            return updated >= minDate;
          });
        }

        if (updatedAtMax) {
          const maxDate = new Date(updatedAtMax);
          filteredOrders = filteredOrders.filter((o: any) => {
            const updated = new Date(o.dateUpdated || o.updatedAt || 0);
            return updated <= maxDate;
          });
        }

        // Limit after filtering
        filteredOrders = filteredOrders.slice(0, actualLimit);

        // Clean response data
        const cleanedOrders = cleanResponseData(filteredOrders);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              count: filteredOrders.length,
              limit: actualLimit,
              source: 'qdrant',
              access_mode: 'sync',
              filters_applied: {
                createdAtMin,
                createdAtMax,
                updatedAtMin,
                updatedAtMax,
                email,
                status
              },
              orders: cleanedOrders
            })
          }]
        };
      } else {
        console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');

        // Build filters using correct parameter names
        const filters: ShopRenterOrderFilters = {};
        if (status) filters.status = status;
        if (email) filters.email = email;
        if (createdAtMin) filters.createdAtMin = createdAtMin;
        if (createdAtMax) filters.createdAtMax = createdAtMax;
        if (updatedAtMin) filters.updatedAtMin = updatedAtMin;
        if (updatedAtMax) filters.updatedAtMax = updatedAtMax;

        // Fetch orders from ShopRenter API
        const response = await fetchOrders(shop_id, 0, actualLimit, filters);
        const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);

        console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });

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

        // Format for LLM (now preserves all ShopRenter fields)
        const formattedOrders = limitedOrders.map(formatOrderForLlm);

        // Clean response data (removes URLs, empty values)
        const cleanedOrders = cleanResponseData(formattedOrders);

        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              count: formattedOrders.length,
              limit: actualLimit,
              source: 'api',
              access_mode: 'sync',
              filters_applied: {
                createdAtMin,
                createdAtMax,
                updatedAtMin,
                updatedAtMax,
                email,
                status
              },
              orders: cleanedOrders
            })
          }]
        };
      }
    }

    // Fallback (should not reach here)
    return {
      content: [{
        type: 'text',
        text: JSON.stringify({ error: 'Invalid access policy configuration' })
      }],
      isError: true
    };
  } catch (error) {
    console.error('[MCP ShopRenter] 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 shoprenter_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 ShopRenter API
    const response = await fetchCustomers(shop_id, 0, 1, { email });
    const customers = Array.isArray(response) ? response : (response.data || response.customers || []);

    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]);

    // Clean response data
    const cleanedCustomer = cleanResponseData(customer);

    return {
      content: [{
        type: 'text',
        text: JSON.stringify({
          source: isApiOnlyMode(policy) ? 'api_direct' : 'api',
          access_mode: policy,
          notice: isApiOnlyMode(policy) ? createApiOnlyNotice('customers') : undefined,
          customer: cleanedCustomer
        })
      }]
    };
  } catch (error) {
    console.error('[MCP ShopRenter] 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 ShopRenter] 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 'shoprenter_get_products':
      return await handleGetProducts(args);

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

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

    case 'shoprenter_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 'shoprenter_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 'shoprenter_list_customers':
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: 'This tool has been removed. Use shoprenter_get_customer with email parameter instead.'
          })
        }],
        isError: true
      };

    case 'shoprenter_get_customer_orders':
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            error: 'This tool has been removed. Use shoprenter_list_orders with 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 ShopRenter] Error handling request:', error);
    sendSseMessage(
      controller,
      createJsonRpcError(
        id!,
        JsonRpcErrorCode.INTERNAL_ERROR,
        error instanceof Error ? error.message : 'Internal error'
      )
    );
  }

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