'use strict';
/**
 * ============================================================
 * © 2025 Diploy — a brand of Bisht Technologies Private Limited
 * Original Author: BTPL Engineering Team
 * Website: https://diploy.in
 * Contact: cs@diploy.in
 *
 * Distributed under the Envato / CodeCanyon License Agreement.
 * Licensed to the purchaser for use as defined by the
 * Envato Market (CodeCanyon) Regular or Extended License.
 *
 * You are NOT permitted to redistribute, resell, sublicense,
 * or share this source code, in whole or in part.
 * Respect the author's rights and Envato licensing terms.
 * ============================================================
 */

import { Router, Request, Response } from "express";
import { RouteContext, AuthRequest } from "./common";
import { eq, and } from "drizzle-orm";
import { llmModels, flows, FlowNode, FlowEdge, knowledgeBase } from "@shared/schema";
import { ElevenLabsService } from "../services/elevenlabs";
import { ElevenLabsPoolService } from "../services/elevenlabs-pool";
import { OpenAIPoolService } from "../engines/plivo/services/openai-pool.service";
import { IncomingAgentService } from "../services/incoming-agent";
import { FlowAgentService } from "../services/flow-agent";
import { setupRAGToolForAgent, isRAGEnabled } from "../services/rag-elevenlabs-tool";

export function createAgentRoutes(ctx: RouteContext): Router {
  const router = Router();
  const { db, storage, authenticateToken, authenticateHybrid, elevenLabsService, upload } = ctx;

  // ========================================
  // Agent CRUD Routes
  // ========================================

  router.get("/api/agents", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      let agents = await storage.getUserAgents(req.userId!);
      
      const typeFilter = req.query.type as string | undefined;
      if (typeFilter && (typeFilter === 'incoming' || typeFilter === 'flow')) {
        agents = agents.filter(agent => agent.type === typeFilter || agent.type === 'flow');
      }
      
      res.json(agents);
    } catch (error: any) {
      console.error("Get agents error:", error);
      res.status(500).json({ error: "Failed to get agents" });
    }
  });

  router.post("/api/agents", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { 
        type, 
        name, 
        voiceTone, 
        personality, 
        systemPrompt, 
        config,
        elevenLabsVoiceId,
        firstMessage,
        language,
        llmModel,
        temperature,
        knowledgeBaseIds,
        transferEnabled,
        transferPhoneNumber,
        transferMessage,
        detectLanguageEnabled,
        endConversationEnabled,
        appointmentBookingEnabled,
        voiceStability,
        voiceSimilarityBoost,
        voiceSpeed,
        telephonyProvider,
        openaiVoice
      } = req.body;

      const normalizedType = (type === 'incoming' || type === 'flow') ? 'flow' : null;
      if (!normalizedType) {
        return res.status(400).json({ error: "Valid agent type is required" });
      }

      if (!name) {
        return res.status(400).json({ error: "Agent name is required" });
      }

      if (!systemPrompt && !req.body.flowId) {
        return res.status(400).json({ error: "System prompt is required for LLM-based agents" });
      }

      // Voice validation depends on telephony provider
      // OpenAI-based providers (plivo, twilio_openai, openai-sip) use OpenAI voices, not ElevenLabs
      // SIP providers (elevenlabs-sip, openai-sip) need special handling
      const isOpenAIProvider = telephonyProvider === 'plivo' || telephonyProvider === 'twilio_openai' || telephonyProvider === 'openai-sip';
      const isSipProvider = telephonyProvider === 'elevenlabs-sip' || telephonyProvider === 'openai-sip';
      
      if (isOpenAIProvider) {
        console.log(`📞 Creating ${telephonyProvider} agent with OpenAI voice: ${openaiVoice || 'alloy'}`);
      } else {
        if (!elevenLabsVoiceId) {
          return res.status(400).json({ error: "Voice ID is required" });
        }
      }

      if (transferEnabled && !transferPhoneNumber?.trim()) {
        return res.status(400).json({ error: "Transfer phone number is required when call transfer is enabled" });
      }

      // Sanitize sipPhoneNumberId: convert empty string to null to avoid foreign key constraint violation
      if ('sipPhoneNumberId' in req.body && req.body.sipPhoneNumberId === '') {
        req.body.sipPhoneNumberId = null;
      }

      const user = await storage.getUser(req.userId!);
      if (!user) {
        return res.status(404).json({ error: "User not found" });
      }

      const plan = await storage.getPlanByName(user.planType || 'free');
      if (!plan) {
        return res.status(500).json({ error: "Plan configuration not found" });
      }

      const existingAgents = await storage.getUserAgents(req.userId!);
      // Skip limit check if explicitly unlimited (-1 or 999)
      if (plan.maxAgents !== -1 && plan.maxAgents !== 999 && existingAgents.length >= plan.maxAgents) {
        return res.status(403).json({ 
          error: `Hiring Agent limit reached. Your ${plan.displayName} allows maximum ${plan.maxAgents} hiring agent(s).`,
          upgradeRequired: true
        });
      }

      if (llmModel) {
        const { getUserPlanCapabilities } = await import('../services/membership-service');
        const capabilities = await getUserPlanCapabilities(req.userId!);
        
        if (!capabilities.canChooseLlm) {
          const { or } = await import('drizzle-orm');
          const requestedModel = await db
            .select({ tier: llmModels.tier })
            .from(llmModels)
            .where(or(eq(llmModels.name, llmModel), eq(llmModels.modelId, llmModel)))
            .limit(1);
          
          const modelTier = requestedModel.length > 0 ? requestedModel[0].tier : null;
          
          if (modelTier && modelTier !== 'free') {
            return res.status(403).json({
              error: "Plan upgrade required",
              message: `Your ${capabilities.planDisplayName} plan only allows free-tier LLM models. Please upgrade to Pro to use premium models.`,
              upgradeRequired: true
            });
          }
        }
      }

      let elevenLabsAgentId = null;
      let effectiveLlmModelId: string | null = "gpt-4o-mini";
      
      if (llmModel) {
        const modelRecord = await db
          .select({ modelId: llmModels.modelId })
          .from(llmModels)
          .where(eq(llmModels.name, llmModel))
          .limit(1);
        
        if (modelRecord.length > 0) {
          effectiveLlmModelId = modelRecord[0].modelId;
          console.log(`📝 Using user-selected LLM model: ${llmModel} → ${effectiveLlmModelId}`);
        } else {
          effectiveLlmModelId = llmModel;
          console.log(`📝 Using user-provided LLM model ID: ${effectiveLlmModelId}`);
        }
      } else {
        const defaultSetting = await storage.getGlobalSetting('default_llm_free');
        if (defaultSetting?.value) {
          const displayName = String(defaultSetting.value).replace(/^"|"$/g, '');
          console.log(`📝 Admin default LLM display name: ${displayName}`);
          
          const modelRecord = await db
            .select({ modelId: llmModels.modelId })
            .from(llmModels)
            .where(eq(llmModels.name, displayName))
            .limit(1);
          
          if (modelRecord.length > 0) {
            effectiveLlmModelId = modelRecord[0].modelId;
            console.log(`📝 Resolved to model ID: ${effectiveLlmModelId}`);
          } else {
            console.log(`⚠️  Could not find model for "${displayName}", using default: ${effectiveLlmModelId}`);
          }
        }
      }

      // Validate that the model is a conversational model, not a transcription model
      // Transcription models like "scribe_v2_realtime" are not valid for ElevenLabs Conversational AI
      const INVALID_TRANSCRIPTION_MODELS = ['scribe_v2_realtime', 'scribe_v2', 'scribe'];
      if (effectiveLlmModelId && INVALID_TRANSCRIPTION_MODELS.some(m => effectiveLlmModelId!.toLowerCase().includes(m))) {
        return res.status(400).json({ 
          error: "Invalid LLM model for conversational agents",
          message: "Scribe models are designed for transcription, not conversational AI. Please select a different LLM model such as GPT-4o Mini, Claude 3, or Gemini."
        });
      }

      let usedCredentialId: string | null = null;

      const { flowId, maxDurationSeconds } = req.body;

      if (!isOpenAIProvider && !flowId) {
        const credential = await ElevenLabsPoolService.getUserCredential(req.userId!);
        if (!credential) {
          return res.status(500).json({ error: "No available ElevenLabs API keys" });
        }
        usedCredentialId = credential.id;

        try {
          const knowledgeBases: Array<{ type: string; title: string; elevenLabsDocId: string }> = [];
          if (knowledgeBaseIds && Array.isArray(knowledgeBaseIds) && knowledgeBaseIds.length > 0) {
            console.log(`📚 Preparing ${knowledgeBaseIds.length} knowledge base(s) for agent creation`);
            
            for (const kbId of knowledgeBaseIds) {
              try {
                const kbItem = await storage.getKnowledgeBaseItem(kbId);
                
                if (!kbItem) {
                  console.warn(`⚠️  Knowledge base item ${kbId} not found, skipping`);
                  continue;
                }

                if (!kbItem.elevenLabsDocId) {
                  console.warn(`⚠️  Knowledge base item ${kbId} has no ElevenLabs doc ID, skipping`);
                  continue;
                }

                console.log(`   Adding KB "${kbItem.title}" (${kbItem.elevenLabsDocId})`);
                knowledgeBases.push({
                  type: kbItem.type,
                  title: kbItem.title,
                  elevenLabsDocId: kbItem.elevenLabsDocId
                });
              } catch (error: any) {
                console.error(`   ❌ Failed to fetch KB ${kbId}:`, error.message);
              }
            }
          }

          const incomingElevenLabsService = new ElevenLabsService(credential.apiKey);

          const agentResponse = await incomingElevenLabsService.createAgent({
            name,
            voice_id: elevenLabsVoiceId,
            prompt: systemPrompt,
            first_message: firstMessage || "Hello! How can I help you today?",
            language: language || "en",
            model: effectiveLlmModelId!,
            temperature: temperature || 0.5,
            personality: personality || "helpful",
            voice_tone: voiceTone || "professional",
            knowledge_bases: knowledgeBases.length > 0 ? knowledgeBases : undefined,
            transferEnabled: transferEnabled || false,
            transferPhoneNumber: transferPhoneNumber || undefined,
            detectLanguageEnabled: detectLanguageEnabled || false,
            endConversationEnabled: endConversationEnabled || false,
            voiceStability: voiceStability ?? 0.55,
            voiceSimilarityBoost: voiceSimilarityBoost ?? 0.85,
            voiceSpeed: voiceSpeed ?? 1.0,
            skipWorkflow: true,
          });

          elevenLabsAgentId = agentResponse.agent_id;
        } catch (error) {
          console.error("Error creating ElevenLabs agent:", error);
          return res.status(500).json({ error: "Failed to create ElevenLabs agent" });
        }
      }
      
      if (!isOpenAIProvider && flowId) {
        const [flow] = await db
          .select()
          .from(flows)
          .where(eq(flows.id, flowId));

        if (!flow) {
          return res.status(404).json({ error: "Selected flow not found" });
        }

        try {
          const result = await FlowAgentService.createInElevenLabs({
            userId: req.userId!,
            name,
            flowId,
            elevenLabsVoiceId: elevenLabsVoiceId!,
            systemPrompt: systemPrompt || undefined,
            firstMessage: firstMessage || undefined,
            language: language || 'en',
            llmModel: effectiveLlmModelId || undefined,
            temperature: temperature ?? 0.3,
            maxDurationSeconds: maxDurationSeconds || 600,
            voiceStability: voiceStability ?? 0.55,
            voiceSimilarityBoost: voiceSimilarityBoost ?? 0.85,
            voiceSpeed: voiceSpeed ?? 1.0,
            detectLanguageEnabled: detectLanguageEnabled || false,
            knowledgeBaseIds: knowledgeBaseIds || undefined,
          });
          
          elevenLabsAgentId = result.elevenLabsAgentId;
          usedCredentialId = result.credentialId;
          console.log(`✅ [Flow Agent Create] ElevenLabs agent created via FlowAgentService: ${elevenLabsAgentId}`);
        } catch (error: any) {
          console.error("Error creating ElevenLabs Flow agent:", error);
          const statusCode = error.status || 500;
          return res.status(statusCode).json({ 
            error: "Failed to create ElevenLabs Flow agent: " + error.message,
            code: error.code || 'INTERNAL_ERROR'
          });
        }
      }

      if (isOpenAIProvider) {
        console.log(`📞 [Agent Create] Creating ${telephonyProvider} agent "${name}" with OpenAI voice: ${openaiVoice || 'alloy'}`);
      }

      const agent = await storage.createAgent({
        userId: req.userId!,
        type: normalizedType,
        name,
        voiceTone: voiceTone || null,
        personality: personality || null,
        systemPrompt,
        config: config || null,
        elevenLabsAgentId,
        elevenLabsCredentialId: usedCredentialId,
        elevenLabsVoiceId: elevenLabsVoiceId || null,
        firstMessage: firstMessage || null,
        language: language || null,
        llmModel: effectiveLlmModelId,
        temperature: temperature ?? null,
        knowledgeBaseIds: knowledgeBaseIds || null,
        transferEnabled: transferEnabled || false,
        transferPhoneNumber: transferPhoneNumber || null,
        detectLanguageEnabled: detectLanguageEnabled || false,
        endConversationEnabled: endConversationEnabled || false,
        appointmentBookingEnabled: appointmentBookingEnabled || false,
        flowId: flowId || null,
        maxDurationSeconds: maxDurationSeconds || null,
        voiceStability: voiceStability ?? 0.55,
        voiceSimilarityBoost: voiceSimilarityBoost ?? 0.85,
        voiceSpeed: voiceSpeed ?? 1.0,
        // Telephony provider: preserve SIP providers, OpenAI providers, otherwise default to twilio
        telephonyProvider: isSipProvider ? telephonyProvider : (isOpenAIProvider ? telephonyProvider : 'twilio'),
        openaiVoice: isOpenAIProvider ? (openaiVoice || 'alloy') : null,
      });

      if (usedCredentialId) {
        try {
          await ElevenLabsPoolService.updateAssignmentCount(usedCredentialId, true);
          console.log(`📊 [Agent Create] Incremented agent count for credential ${usedCredentialId}`);
        } catch (countError) {
          console.warn("Failed to update credential agent count:", countError);
        }
      }

      if (flowId) {
        try {
          await db
            .update(flows)
            .set({ agentId: agent.id })
            .where(eq(flows.id, flowId));
          console.log(`✅ [Flow Agent Create] Flow ${flowId} now references agent ${agent.id}`);
        } catch (flowUpdateError) {
          console.warn("Failed to update flow reference:", flowUpdateError);
        }
      }

      try {
        await ElevenLabsPoolService.syncExistingAgents();
      } catch (poolError) {
        console.warn("Failed to sync agent to pool:", poolError);
      }

      let updatedAgent = agent;
      
      if (appointmentBookingEnabled && elevenLabsAgentId && usedCredentialId) {
        try {
          console.log(`📅 [Agent Create] Adding appointment booking tool for ElevenLabs agent ${elevenLabsAgentId}`);
          const credential = await ElevenLabsPoolService.getCredentialForAgent(agent.id);
          if (credential) {
            const appointmentElevenLabsService = new ElevenLabsService(credential.apiKey);
            await appointmentElevenLabsService.updateAgent(elevenLabsAgentId, {
              appointmentBookingEnabled: true,
              skipWorkflowRebuild: true,
            });
            console.log(`✅ [Agent Create] Appointment booking tool added`);
          }
        } catch (appointmentError) {
          console.warn("Failed to add appointment booking tool (non-fatal):", appointmentError);
        }
      }
      
      if (elevenLabsAgentId && isRAGEnabled() && knowledgeBaseIds && knowledgeBaseIds.length > 0) {
        try {
          console.log(`📚 [Agent Create] Setting up RAG workspace tool for agent ${agent.id}`);
          
          const systemTools: any[] = [];
          
          if (transferEnabled && transferPhoneNumber) {
            systemTools.push({
              type: "system",
              name: "transfer_to_number",
              description: transferMessage || "Transfer the call to a human when the customer requests to speak to a human or if the query is beyond AI capabilities",
              phone_number: transferPhoneNumber,
            });
          }
          if (detectLanguageEnabled) {
            systemTools.push({
              type: "system",
              name: "detect_language",
              description: "Detect the language the user is speaking",
            });
          }
          if (endConversationEnabled) {
            systemTools.push({
              type: "system",
              name: "end_conversation",
              description: "End the conversation when the user indicates they are done",
            });
          }
          
          await setupRAGToolForAgent(
            agent.id,
            elevenLabsAgentId,
            knowledgeBaseIds,
            systemTools
          );
          console.log(`✅ [Agent Create] RAG tool setup complete`);
          
          updatedAgent = await storage.getAgent(agent.id) || agent;
        } catch (ragError) {
          console.warn("Failed to setup RAG tool (non-fatal):", ragError);
        }
      }
      
      if (elevenLabsVoiceId) {
        setImmediate(async () => {
          try {
            const { VoiceSyncService } = await import("../services/voice-sync");
            
            if (elevenLabsVoiceId.startsWith('21m00') || elevenLabsVoiceId.length < 20) {
              console.log(`🔊 Voice ${elevenLabsVoiceId} is a default voice, skipping sync`);
              return;
            }
            
            const sharedVoices = await elevenLabsService.listSharedVoices({ search: '' });
            const matchingVoice = sharedVoices.voices.find(v => v.voice_id === elevenLabsVoiceId);
            
            if (matchingVoice?.public_owner_id) {
              console.log(`🔊 Starting async voice sync for ${elevenLabsVoiceId} (${matchingVoice.name})`);
              const result = await VoiceSyncService.syncVoiceToAllCredentials(
                elevenLabsVoiceId,
                matchingVoice.public_owner_id,
                matchingVoice.name
              );
              console.log(`🔊 Voice sync complete: ${result.synced} synced, ${result.failed} failed`);
            } else {
              console.log(`🔊 Voice ${elevenLabsVoiceId} not found in shared library, skipping pool sync`);
            }
          } catch (syncError) {
            console.warn(`⚠️ Async voice sync failed:`, syncError);
          }
        });
      }
      
      res.json(updatedAgent);
    } catch (error: any) {
      console.error("Create agent error:", error);
      res.status(500).json({ error: "Failed to create agent" });
    }
  });

  router.get("/api/agents/:id", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.id);
      if (!agent || agent.userId !== req.userId) {
        return res.status(404).json({ error: "Agent not found" });
      }

      res.json(agent);
    } catch (error: any) {
      console.error("Get agent error:", error);
      res.status(500).json({ error: "Failed to get agent" });
    }
  });

  router.patch("/api/agents/:id", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.id);
      if (!agent || agent.userId !== req.userId) {
        return res.status(404).json({ error: "Agent not found" });
      }

      if (req.body.transferEnabled === true && !req.body.transferPhoneNumber?.trim()) {
        return res.status(400).json({ error: "Transfer phone number is required when call transfer is enabled" });
      }

      // Sanitize sipPhoneNumberId: convert empty string to null to avoid foreign key constraint violation
      if ('sipPhoneNumberId' in req.body && req.body.sipPhoneNumberId === '') {
        req.body.sipPhoneNumberId = null;
      }

      try {
        console.log(`📝 [Version History] Agent update for ${agent.id} (${agent.type})`);
        console.log(`   Request body keys: ${Object.keys(req.body).join(', ')}`);
        
        const latestVersion = await storage.getLatestAgentVersion(agent.id);
        const nextVersionNumber = (latestVersion?.versionNumber || 0) + 1;
        
        const currentSnapshot = {
          name: agent.name,
          type: agent.type,
          voiceTone: agent.voiceTone,
          personality: agent.personality,
          systemPrompt: agent.systemPrompt,
          language: agent.language,
          firstMessage: agent.firstMessage,
          llmModel: agent.llmModel,
          temperature: agent.temperature,
          elevenLabsVoiceId: agent.elevenLabsVoiceId,
          voiceStability: agent.voiceStability,
          voiceSimilarityBoost: agent.voiceSimilarityBoost,
          voiceSpeed: agent.voiceSpeed,
          transferPhoneNumber: agent.transferPhoneNumber,
          transferEnabled: agent.transferEnabled,
          detectLanguageEnabled: agent.detectLanguageEnabled,
          endConversationEnabled: agent.endConversationEnabled,
          knowledgeBaseIds: agent.knowledgeBaseIds,
          maxDurationSeconds: agent.maxDurationSeconds,
          config: agent.config as Record<string, unknown> | null,
        };
        
        const changedFields: string[] = [];
        const changeDescriptions: string[] = [];
        
        const fieldsToCheck = [
          'name', 'voiceTone', 'personality', 'systemPrompt', 'language',
          'firstMessage', 'llmModel', 'temperature', 'elevenLabsVoiceId',
          'voiceStability', 'voiceSimilarityBoost', 'voiceSpeed',
          'transferPhoneNumber', 'transferEnabled', 'detectLanguageEnabled',
          'endConversationEnabled', 'knowledgeBaseIds', 'maxDurationSeconds',
          'flowId', 'config'
        ];
        
        for (const field of fieldsToCheck) {
          const reqValue = req.body[field];
          const agentValue = (agent as any)[field];
          
          if (reqValue !== undefined) {
            let hasChanged = false;
            
            if (field === 'config' || field === 'knowledgeBaseIds') {
              hasChanged = JSON.stringify(reqValue) !== JSON.stringify(agentValue);
            } else {
              hasChanged = reqValue !== agentValue;
            }
            
            if (hasChanged) {
              changedFields.push(field);
              if (field === 'systemPrompt' || field === 'firstMessage') {
                changeDescriptions.push(`Updated ${field.replace(/([A-Z])/g, ' $1').toLowerCase()}`);
              } else if (field === 'config') {
                changeDescriptions.push('Updated agent configuration');
              } else if (field === 'flowId') {
                changeDescriptions.push('Changed conversation flow');
              } else {
                changeDescriptions.push(`Changed ${field.replace(/([A-Z])/g, ' $1').toLowerCase()}`);
              }
            }
          }
        }
        
        if (changedFields.length > 0) {
          console.log(`   ✅ Creating version ${nextVersionNumber}: ${changedFields.join(', ')}`);
          await storage.createAgentVersion({
            agentId: agent.id,
            versionNumber: nextVersionNumber,
            snapshot: currentSnapshot,
            changesSummary: changeDescriptions.join(', ') || 'Configuration updated',
            changedFields,
            editedBy: req.userId!,
            note: null,
          });
        } else {
          console.log(`   ⏭️ No changes detected, skipping version creation`);
        }
      } catch (versionError) {
        console.warn("Failed to create agent version:", versionError);
      }

      const { 
        name, 
        systemPrompt, 
        elevenLabsVoiceId, 
        language, 
        llmModel, 
        knowledgeBaseIds, 
        transferEnabled, 
        transferPhoneNumber,
        detectLanguageEnabled,
        endConversationEnabled,
        appointmentBookingEnabled,
        flowId: newFlowId,
        maxDurationSeconds: newMaxDuration,
        voiceStability,
        voiceSimilarityBoost,
        voiceSpeed
      } = req.body;

      if (llmModel && llmModel !== agent.llmModel) {
        const { getUserPlanCapabilities } = await import('../services/membership-service');
        const capabilities = await getUserPlanCapabilities(req.userId!);
        
        if (!capabilities.canChooseLlm) {
          const { or } = await import('drizzle-orm');
          const requestedModel = await db
            .select({ tier: llmModels.tier })
            .from(llmModels)
            .where(or(eq(llmModels.name, llmModel), eq(llmModels.modelId, llmModel)))
            .limit(1);
          
          const modelTier = requestedModel.length > 0 ? requestedModel[0].tier : null;
          
          if (modelTier && modelTier !== 'free') {
            return res.status(403).json({
              error: "Plan upgrade required",
              message: `Your ${capabilities.planDisplayName} plan only allows free-tier LLM models. Please upgrade to Pro to use premium models.`,
              upgradeRequired: true
            });
          }
        }
      }

      const effectiveFlowId = newFlowId || agent.flowId;

      let resolvedLlmModel: string | null = agent.llmModel;
      if (llmModel) {
        const modelRecord = await db
          .select({ modelId: llmModels.modelId })
          .from(llmModels)
          .where(eq(llmModels.name, llmModel))
          .limit(1);
        resolvedLlmModel = modelRecord.length > 0 ? modelRecord[0].modelId : llmModel;
      }

      const updateBody = {
        ...req.body,
        llmModel: resolvedLlmModel || agent.llmModel,
        temperature: req.body.temperature !== undefined ? req.body.temperature : agent.temperature,
        knowledgeBaseIds: knowledgeBaseIds !== undefined ? knowledgeBaseIds : agent.knowledgeBaseIds,
      };
      await storage.updateAgent(req.params.id, updateBody);

      const updatedAgent = await storage.getAgent(req.params.id);
      if (!updatedAgent) {
        return res.status(500).json({ error: "Failed to retrieve updated agent" });
      }

      const isElevenLabsEngine = !updatedAgent.telephonyProvider || updatedAgent.telephonyProvider === 'twilio' || updatedAgent.telephonyProvider === 'elevenlabs-sip';

      if (agent.elevenLabsAgentId) {
        if (effectiveFlowId) {
          try {
            await FlowAgentService.updateInElevenLabs(
              agent.id,
              agent.elevenLabsAgentId,
              agent,
              {
                name,
                flowId: newFlowId,
                elevenLabsVoiceId,
                systemPrompt,
                firstMessage: req.body.firstMessage,
                language,
                llmModel,
                temperature: req.body.temperature,
                maxDurationSeconds: newMaxDuration,
                detectLanguageEnabled,
                knowledgeBaseIds,
                voiceStability,
                voiceSimilarityBoost,
                voiceSpeed,
              }
            );
          } catch (syncError: any) {
            console.error(`❌ Flow agent ElevenLabs sync failed:`);
            console.error(`   Agent ID: ${agent.id}`);
            console.error(`   ElevenLabs Agent ID: ${agent.elevenLabsAgentId}`);
            console.error(`   Flow ID: ${newFlowId || agent.flowId || 'none'}`);
            console.error(`   Error: ${syncError.message}`);
            if (syncError.details) {
              console.error(`   Details:`, JSON.stringify(syncError.details, null, 2));
            }
            if (syncError.stack) {
              console.error(`   Stack:`, syncError.stack.split('\n').slice(0, 5).join('\n'));
            }
          }
        } else {
          try {
            await IncomingAgentService.updateInElevenLabs(
              agent.id,
              agent.elevenLabsAgentId,
              agent,
              {
                name,
                systemPrompt,
                elevenLabsVoiceId,
                firstMessage: req.body.firstMessage,
                language,
                llmModel,
                temperature: req.body.temperature,
                knowledgeBaseIds,
                transferEnabled,
                transferPhoneNumber,
                detectLanguageEnabled,
                endConversationEnabled,
                appointmentBookingEnabled,
                voiceStability,
                voiceSimilarityBoost,
                voiceSpeed,
                databaseAgentId: agent.id,
              }
            );
          } catch (error: any) {
            console.error("Failed to sync agent to ElevenLabs:", error);
          }
        }
      } else if (isElevenLabsEngine) {
        try {
          console.log(`🔄 [Agent PATCH] Auto-creating ElevenLabs agent for "${updatedAgent.name}" (no elevenLabsAgentId yet)`);
          if (effectiveFlowId) {
            const result = await FlowAgentService.createInElevenLabs({
              userId: req.userId!,
              name: updatedAgent.name,
              flowId: effectiveFlowId,
              elevenLabsVoiceId: updatedAgent.elevenLabsVoiceId || '',
              systemPrompt: updatedAgent.systemPrompt || undefined,
              firstMessage: updatedAgent.firstMessage || undefined,
              language: updatedAgent.language || 'en',
              llmModel: updatedAgent.llmModel || undefined,
              temperature: updatedAgent.temperature ?? 0.3,
              maxDurationSeconds: updatedAgent.maxDurationSeconds || 600,
              voiceStability: updatedAgent.voiceStability ?? 0.55,
              voiceSimilarityBoost: updatedAgent.voiceSimilarityBoost ?? 0.85,
              voiceSpeed: updatedAgent.voiceSpeed ?? 1.0,
              detectLanguageEnabled: updatedAgent.detectLanguageEnabled || false,
              knowledgeBaseIds: updatedAgent.knowledgeBaseIds || undefined,
            });
            await storage.updateAgent(agent.id, {
              elevenLabsAgentId: result.elevenLabsAgentId,
              elevenLabsCredentialId: result.credentialId,
            });
            console.log(`✅ [Agent PATCH] Auto-created Flow ElevenLabs agent: ${result.elevenLabsAgentId}`);
          } else {
            const result = await IncomingAgentService.createInElevenLabs({
              userId: req.userId!,
              name: updatedAgent.name,
              elevenLabsVoiceId: updatedAgent.elevenLabsVoiceId || '',
              systemPrompt: updatedAgent.systemPrompt || 'You are a professional AI assistant.',
              firstMessage: updatedAgent.firstMessage || 'Hello! How can I help you today?',
              language: updatedAgent.language || 'en',
              llmModel: updatedAgent.llmModel || 'gpt-4o-mini',
              temperature: updatedAgent.temperature ?? 0.5,
              personality: updatedAgent.personality || 'professional',
              voiceTone: updatedAgent.voiceTone || 'professional',
              knowledgeBaseIds: updatedAgent.knowledgeBaseIds || [],
              transferEnabled: updatedAgent.transferEnabled || false,
              transferPhoneNumber: updatedAgent.transferPhoneNumber || undefined,
              detectLanguageEnabled: updatedAgent.detectLanguageEnabled || false,
              endConversationEnabled: updatedAgent.endConversationEnabled || false,
              appointmentBookingEnabled: updatedAgent.appointmentBookingEnabled || false,
              voiceStability: updatedAgent.voiceStability ?? 0.55,
              voiceSimilarityBoost: updatedAgent.voiceSimilarityBoost ?? 0.85,
              voiceSpeed: updatedAgent.voiceSpeed ?? 1.0,
              databaseAgentId: agent.id,
            });
            await storage.updateAgent(agent.id, {
              elevenLabsAgentId: result.elevenLabsAgentId,
              elevenLabsCredentialId: result.credentialId,
            });
            console.log(`✅ [Agent PATCH] Auto-created LLM ElevenLabs agent: ${result.elevenLabsAgentId}`);
          }
        } catch (autoCreateError: any) {
          console.error(`❌ [Agent PATCH] Failed to auto-create ElevenLabs agent:`, autoCreateError.message);
        }
      }

      const finalAgent = await storage.getAgent(req.params.id);
      res.json(finalAgent || updatedAgent);
    } catch (error: any) {
      console.error("Update agent error:", error);
      res.status(500).json({ error: "Failed to update agent" });
    }
  });

  router.delete("/api/agents/:id", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.id);
      if (!agent || agent.userId !== req.userId) {
        return res.status(404).json({ error: "Agent not found" });
      }

      if (agent.elevenLabsAgentId) {
        try {
          const credential = await ElevenLabsPoolService.getCredentialForAgent(agent.id);
          if (credential) {
            const agentElevenLabsService = new ElevenLabsService(credential.apiKey);
            await agentElevenLabsService.deleteAgent(agent.elevenLabsAgentId);
            console.log(`✅ Deleted agent ${agent.name} from ElevenLabs (${agent.elevenLabsAgentId})`);
          } else {
            await elevenLabsService.deleteAgent(agent.elevenLabsAgentId);
            console.log(`✅ Deleted agent ${agent.name} from ElevenLabs using default credential`);
          }
        } catch (elevenLabsError: any) {
          console.error(`⚠️ Failed to delete from ElevenLabs (will still delete from database):`, elevenLabsError.message);
        }
      }

      if (agent.elevenLabsCredentialId) {
        try {
          await ElevenLabsPoolService.updateAssignmentCount(agent.elevenLabsCredentialId, false);
          console.log(`📊 [Agent Delete] Decremented agent count for credential ${agent.elevenLabsCredentialId}`);
        } catch (countError) {
          console.warn("Failed to update credential agent count:", countError);
        }
      }

      await storage.deleteAgent(req.params.id);
      res.json({ success: true });
    } catch (error: any) {
      console.error("Delete agent error:", error);
      res.status(500).json({ error: "Failed to delete agent" });
    }
  });

  // ========================================
  // Knowledge Base Routes
  // ========================================

  router.get("/api/knowledge-base", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const items = await storage.getUserKnowledgeBase(req.userId!);
      res.json(items);
    } catch (error: any) {
      console.error("Get knowledge base error:", error);
      res.status(500).json({ error: "Failed to get knowledge base" });
    }
  });

  router.post("/api/knowledge-base", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { type, title, content, url, metadata } = req.body;

      if (!type || !title) {
        return res.status(400).json({ error: "Type and title are required" });
      }

      const currentCount = await storage.getUserKnowledgeBaseCount(req.userId!);
      const limits = await storage.getUserEffectiveLimits(req.userId!);
      const maxKnowledgeBases = typeof limits.maxKnowledgeBases === 'number' ? limits.maxKnowledgeBases : 5;
      
      // Skip limit check if explicitly unlimited (999 or -1)
      if (maxKnowledgeBases !== 999 && maxKnowledgeBases !== -1 && currentCount >= maxKnowledgeBases) {
        return res.status(403).json({ 
          error: `Knowledge base limit reached (${maxKnowledgeBases}). Upgrade your plan or contact support to increase your limit.`
        });
      }

      const storageSize = content ? content.length : 0;

      const item = await storage.createKnowledgeBaseItem({
        userId: req.userId!,
        type,
        title,
        content: content || null,
        url: url || null,
        fileUrl: null,
        metadata: metadata || null,
        storageSize,
      });

      res.json(item);
    } catch (error: any) {
      console.error("Create knowledge base item error:", error);
      res.status(500).json({ error: "Failed to create knowledge base item" });
    }
  });

  router.post("/api/knowledge-base/upload", authenticateHybrid, upload.single('file'), async (req: AuthRequest, res: Response) => {
    try {
      if (!req.file) {
        return res.status(400).json({ error: "No file uploaded" });
      }

      const currentCount = await storage.getUserKnowledgeBaseCount(req.userId!);
      const limits = await storage.getUserEffectiveLimits(req.userId!);
      const maxKnowledgeBases = typeof limits.maxKnowledgeBases === 'number' ? limits.maxKnowledgeBases : 5;
      
      // Skip limit check if explicitly unlimited (999 or -1)
      if (maxKnowledgeBases !== 999 && maxKnowledgeBases !== -1 && currentCount >= maxKnowledgeBases) {
        return res.status(403).json({ 
          error: `Knowledge base limit reached (${maxKnowledgeBases}). Upgrade your plan or contact support to increase your limit.`
        });
      }

      const { name } = req.body;
      const filename = req.file.originalname;
      
      if (req.file.size > 20 * 1024 * 1024) {
        return res.status(400).json({ error: "File size exceeds 20MB limit" });
      }

      const elevenLabsResult = await elevenLabsService.uploadKnowledgeBaseFile(
        req.file.buffer,
        filename,
        name || filename
      );

      const item = await storage.createKnowledgeBaseItem({
        userId: req.userId!,
        type: 'file',
        title: name || filename,
        content: null,
        url: null,
        fileUrl: filename,
        elevenLabsDocId: elevenLabsResult.id,
        metadata: { filename, mimeType: req.file.mimetype },
        storageSize: req.file.size,
      });

      res.json(item);
    } catch (error: any) {
      console.error("Upload knowledge base file error:", error);
      res.status(500).json({ error: error.message || "Failed to upload file" });
    }
  });

  router.post("/api/knowledge-base/url", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { url, name } = req.body;

      if (!url) {
        return res.status(400).json({ error: "URL is required" });
      }

      const currentCount = await storage.getUserKnowledgeBaseCount(req.userId!);
      const limits = await storage.getUserEffectiveLimits(req.userId!);
      const maxKnowledgeBases = typeof limits.maxKnowledgeBases === 'number' ? limits.maxKnowledgeBases : 5;
      
      // Skip limit check if explicitly unlimited (999 or -1)
      if (maxKnowledgeBases !== 999 && maxKnowledgeBases !== -1 && currentCount >= maxKnowledgeBases) {
        return res.status(403).json({ 
          error: `Knowledge base limit reached (${maxKnowledgeBases}). Upgrade your plan or contact support to increase your limit.`
        });
      }

      const elevenLabsResult = await elevenLabsService.addKnowledgeBaseFromUrl(url, name);

      const item = await storage.createKnowledgeBaseItem({
        userId: req.userId!,
        type: 'url',
        title: name || url,
        content: null,
        url: url,
        fileUrl: null,
        elevenLabsDocId: elevenLabsResult.id,
        metadata: { url },
        storageSize: 0,
      });

      res.json(item);
    } catch (error: any) {
      console.error("Add knowledge base URL error:", error);
      res.status(500).json({ error: error.message || "Failed to add URL" });
    }
  });

  router.post("/api/knowledge-base/text", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { text, name } = req.body;

      if (!text || !name) {
        return res.status(400).json({ error: "Text and name are required" });
      }

      const currentCount = await storage.getUserKnowledgeBaseCount(req.userId!);
      const limits = await storage.getUserEffectiveLimits(req.userId!);
      const maxKnowledgeBases = typeof limits.maxKnowledgeBases === 'number' ? limits.maxKnowledgeBases : 5;
      
      // Skip limit check if explicitly unlimited (999 or -1)
      if (maxKnowledgeBases !== 999 && maxKnowledgeBases !== -1 && currentCount >= maxKnowledgeBases) {
        return res.status(403).json({ 
          error: `Knowledge base limit reached (${maxKnowledgeBases}). Upgrade your plan or contact support to increase your limit.`
        });
      }

      if (text.length > 300000) {
        return res.status(400).json({ error: "Text exceeds 300,000 character limit" });
      }

      const elevenLabsResult = await elevenLabsService.addKnowledgeBaseFromText(text, name);

      const item = await storage.createKnowledgeBaseItem({
        userId: req.userId!,
        type: 'text',
        title: name,
        content: text,
        url: null,
        fileUrl: null,
        elevenLabsDocId: elevenLabsResult.id,
        metadata: null,
        storageSize: text.length,
      });

      res.json(item);
    } catch (error: any) {
      console.error("Add knowledge base text error:", error);
      res.status(500).json({ error: error.message || "Failed to add text" });
    }
  });

  router.delete("/api/knowledge-base/:id", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const item = await storage.getKnowledgeBaseItem(req.params.id);
      if (!item || item.userId !== req.userId) {
        return res.status(404).json({ error: "Knowledge base item not found" });
      }

      if (item.elevenLabsDocId) {
        try {
          await elevenLabsService.deleteKnowledgeBase(item.elevenLabsDocId);
        } catch (elevenLabsError: any) {
          console.error("Failed to delete from ElevenLabs:", elevenLabsError.message);
        }
      }

      await storage.deleteKnowledgeBaseItem(req.params.id);
      res.json({ success: true });
    } catch (error: any) {
      console.error("Delete knowledge base item error:", error);
      res.status(500).json({ error: "Failed to delete knowledge base item" });
    }
  });

  // ========================================
  // Agent Version History Routes
  // ========================================
  
  router.get("/api/agents/:agentId/versions", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.agentId);
      if (!agent) {
        return res.status(404).json({ error: "Agent not found" });
      }
      if (agent.userId !== req.userId) {
        return res.status(403).json({ error: "Access denied" });
      }
      
      const versions = await storage.getAgentVersions(req.params.agentId);
      res.json(versions);
    } catch (error: any) {
      console.error("Get agent versions error:", error);
      res.status(500).json({ error: "Failed to get agent versions" });
    }
  });

  router.get("/api/agents/:agentId/versions/:versionNumber", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.agentId);
      if (!agent) {
        return res.status(404).json({ error: "Agent not found" });
      }
      if (agent.userId !== req.userId) {
        return res.status(403).json({ error: "Access denied" });
      }
      
      const versionNumber = parseInt(req.params.versionNumber, 10);
      if (isNaN(versionNumber)) {
        return res.status(400).json({ error: "Invalid version number" });
      }
      
      const version = await storage.getAgentVersionByNumber(req.params.agentId, versionNumber);
      if (!version) {
        return res.status(404).json({ error: "Version not found" });
      }
      
      res.json(version);
    } catch (error: any) {
      console.error("Get agent version error:", error);
      res.status(500).json({ error: "Failed to get agent version" });
    }
  });

  router.post("/api/agents/:agentId/versions/:versionNumber/rollback", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const agent = await storage.getAgent(req.params.agentId);
      if (!agent) {
        return res.status(404).json({ error: "Agent not found" });
      }
      if (agent.userId !== req.userId) {
        return res.status(403).json({ error: "Access denied" });
      }
      
      const versionNumber = parseInt(req.params.versionNumber, 10);
      if (isNaN(versionNumber)) {
        return res.status(400).json({ error: "Invalid version number" });
      }
      
      const targetVersion = await storage.getAgentVersionByNumber(req.params.agentId, versionNumber);
      if (!targetVersion) {
        return res.status(404).json({ error: "Version not found" });
      }
      
      const latestVersion = await storage.getLatestAgentVersion(req.params.agentId);
      const nextVersionNumber = (latestVersion?.versionNumber || 0) + 1;
      
      const currentSnapshot = {
        name: agent.name,
        type: agent.type,
        voiceTone: agent.voiceTone,
        personality: agent.personality,
        systemPrompt: agent.systemPrompt,
        language: agent.language,
        firstMessage: agent.firstMessage,
        llmModel: agent.llmModel,
        temperature: agent.temperature,
        elevenLabsVoiceId: agent.elevenLabsVoiceId,
        voiceStability: agent.voiceStability,
        voiceSimilarityBoost: agent.voiceSimilarityBoost,
        voiceSpeed: agent.voiceSpeed,
        transferPhoneNumber: agent.transferPhoneNumber,
        transferEnabled: agent.transferEnabled,
        detectLanguageEnabled: agent.detectLanguageEnabled,
        endConversationEnabled: agent.endConversationEnabled,
        knowledgeBaseIds: agent.knowledgeBaseIds,
        maxDurationSeconds: agent.maxDurationSeconds,
        config: agent.config as Record<string, unknown> | null,
      };
      
      await storage.createAgentVersion({
        agentId: req.params.agentId,
        versionNumber: nextVersionNumber,
        snapshot: currentSnapshot,
        changesSummary: `Snapshot before rollback to version ${versionNumber}`,
        changedFields: [],
        editedBy: req.userId!,
        note: req.body.note || null,
      });
      
      const targetSnapshot = targetVersion.snapshot as typeof currentSnapshot;
      await storage.updateAgent(req.params.agentId, {
        name: targetSnapshot.name,
        voiceTone: targetSnapshot.voiceTone,
        personality: targetSnapshot.personality,
        systemPrompt: targetSnapshot.systemPrompt,
        language: targetSnapshot.language,
        firstMessage: targetSnapshot.firstMessage,
        llmModel: targetSnapshot.llmModel,
        temperature: targetSnapshot.temperature,
        elevenLabsVoiceId: targetSnapshot.elevenLabsVoiceId,
        voiceStability: targetSnapshot.voiceStability,
        voiceSimilarityBoost: targetSnapshot.voiceSimilarityBoost,
        voiceSpeed: targetSnapshot.voiceSpeed,
        transferPhoneNumber: targetSnapshot.transferPhoneNumber,
        transferEnabled: targetSnapshot.transferEnabled,
        detectLanguageEnabled: targetSnapshot.detectLanguageEnabled,
        endConversationEnabled: targetSnapshot.endConversationEnabled,
        knowledgeBaseIds: targetSnapshot.knowledgeBaseIds,
        maxDurationSeconds: targetSnapshot.maxDurationSeconds,
        config: targetSnapshot.config,
        updatedAt: new Date(),
      });
      
      if (agent.elevenLabsAgentId) {
        try {
          const credential = await ElevenLabsPoolService.getCredentialForAgent(agent.id);
          if (credential) {
            const rollbackElevenLabsService = new ElevenLabsService(credential.apiKey);
            await rollbackElevenLabsService.updateAgent(agent.elevenLabsAgentId, {
              name: targetSnapshot.name,
              first_message: targetSnapshot.firstMessage || undefined,
              prompt: targetSnapshot.systemPrompt || undefined,
              voice_id: targetSnapshot.elevenLabsVoiceId || undefined,
              language: targetSnapshot.language || 'en',
              model: targetSnapshot.llmModel || undefined,
              temperature: targetSnapshot.temperature || undefined,
            });
          }
        } catch (syncError) {
          console.warn("Failed to sync rollback with ElevenLabs:", syncError);
        }
      }
      
      const updatedAgent = await storage.getAgent(req.params.agentId);
      
      res.json({
        success: true,
        message: `Rolled back to version ${versionNumber}`,
        agent: updatedAgent,
        previousVersionNumber: nextVersionNumber,
      });
    } catch (error: any) {
      console.error("Rollback agent version error:", error);
      res.status(500).json({ error: "Failed to rollback agent version" });
    }
  });

  // ========================================
  // Voices Routes (Agent-related)
  // ========================================

  router.get("/api/voices", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const voices = await storage.getUserVoices(req.userId!);
      res.json(voices);
    } catch (error: any) {
      console.error("Get voices error:", error);
      res.status(500).json({ error: "Failed to get voices" });
    }
  });

  router.post("/api/voices/preview", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { voiceId, text, voiceSettings, modelId } = req.body;
      
      if (!voiceId) {
        return res.status(400).json({ error: "Voice ID is required" });
      }
      
      const previewText = text || "Hello! This is a preview of how I'll sound. I can adjust my tone and style based on your preferences.";
      
      if (previewText.length > 500) {
        return res.status(400).json({ error: "Preview text cannot exceed 500 characters" });
      }
      
      const credential = await ElevenLabsPoolService.getUserCredential(req.userId!);
      if (!credential) {
        return res.status(500).json({ error: "No available ElevenLabs API keys" });
      }
      
      const previewService = new ElevenLabsService(credential.apiKey);
      
      const audioBuffer = await previewService.generateVoicePreview({
        voiceId,
        text: previewText,
        voiceSettings,
        modelId,
      });
      
      res.setHeader('Content-Type', 'audio/mpeg');
      res.setHeader('Content-Length', audioBuffer.length);
      res.setHeader('Cache-Control', 'no-cache');
      
      res.send(audioBuffer);
    } catch (error: any) {
      console.error("Voice preview error:", error);
      res.status(500).json({ error: error.message || "Failed to generate voice preview" });
    }
  });

  // ========================================
  // OpenAI Voice Preview Route
  // ========================================

  router.post("/api/openai/voices/preview", authenticateHybrid, async (req: AuthRequest, res: Response) => {
    try {
      const { voiceId, text, speed } = req.body;
      
      if (!voiceId) {
        return res.status(400).json({ error: "Voice ID is required" });
      }
      
      // const validVoices = ["alloy", "echo", "shimmer", "ash", "ballad", "coral", "sage", "verse", "cedar", "marin"];
      const validVoices = [
  "nova",
  "shimmer",
  "echo",
  "onyx",
  "fable",
  "alloy",
  "ash",
  "sage",
  "coral"
];
      if (!validVoices.includes(voiceId)) {
        return res.status(400).json({ error: `Invalid voice. Must be one of: ${validVoices.join(", ")}` });
      }
      
      const previewText = text || "Hello! This is a preview of how I'll sound. I can adjust my tone and style based on your preferences.";
      
      if (previewText.length > 500) {
        return res.status(400).json({ error: "Preview text cannot exceed 500 characters" });
      }

      const credential = await OpenAIPoolService.getOpenAIKeyFromSettings();
      // console.log("CHECK credential", credential)
      
      // const credential = await OpenAIPoolService.getLeastLoadedCredential();
      if (!credential) {
        return res.status(500).json({ error: "No available OpenAI API keys" });
      }
      
      
      
      const response = await fetch("https://api.openai.com/v1/audio/speech", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${credential}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          model: "tts-1",
          input: previewText,
          voice: voiceId,
          response_format: "mp3",
          speed: speed || 1.0,
        }),
      });
      
      if (!response.ok) {
        const errorText = await response.text();
        console.error("OpenAI TTS error:", errorText);
        return res.status(500).json({ error: "Failed to generate voice preview" });
      }
      
      const audioBuffer = Buffer.from(await response.arrayBuffer());
      
      res.setHeader('Content-Type', 'audio/mpeg');
      res.setHeader('Content-Length', audioBuffer.length);
      res.setHeader('Cache-Control', 'no-cache');
      
      res.send(audioBuffer);
    } catch (error: any) {
      console.error("OpenAI voice preview error:", error);
      res.status(500).json({ error: error.message || "Failed to generate voice preview" });
    }
  });

  return router;
}
