/**
 * coze-chat-stream Edge Function
 * C端消费者聊天 - 流式输出版本
 * 
 * 功能：
 * 1. 接收用户消息，调用 Coze API
 * 2. 返回 SSE 流式响应，实时推送文字
 * 3. 最终返回结构化数据（picks等）
 * 4. 记录测试结果供 Coze 查询反馈
 */

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4';

// === AI Hub routing (auto-injected) ===
const _HUB_KEY = Deno.env.get('AI_HUB_API_KEY') || '';
const _HUB_BASE = (Deno.env.get('AI_HUB_BASE_URL') || '').replace(/\/+$/, '');
const _USE_HUB = !!(_HUB_KEY && _HUB_BASE);
const _AI_CHAT_URL = _USE_HUB ? `${_HUB_BASE}/chat/completions` : _AI_CHAT_URL;
const _AI_CHAT_KEY = _USE_HUB ? _HUB_KEY : (Deno.env.get('LOVABLE_API_KEY') || '');
const _AI_CHAT_DEFAULT_MODEL = Deno.env.get('AI_HUB_DEFAULT_CHAT_MODEL') || 'agent-default';
const _mapAiModel = (m: string) => (_USE_HUB && /^(google|openai|anthropic)\//i.test(m || '')) ? _AI_CHAT_DEFAULT_MODEL : m;
// === end AI Hub routing ===


const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-trace-id, x-user-id',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
};

interface CozeRequest {
  message: string;
  conversationId?: string;
  inputs: {
    user_id?: string;
    trace_id: string;
    user_context?: string;
    catalog?: Array<{
      id: string;
      name: string;
      price: number;
      stock_quantity?: number;
      category?: string;
      description?: string;
    }>;
  };
}

// ========================
// Agent 规范缓存
// ========================
let cachedAgentSpec: any = null;
let cacheTimestamp = 0;
const CACHE_TTL_MS = 5 * 60 * 1000;

async function fetchAgentSpec(): Promise<any> {
  const now = Date.now();
  
  if (cachedAgentSpec && (now - cacheTimestamp) < CACHE_TTL_MS) {
    return cachedAgentSpec;
  }
  
  try {
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const specUrl = `${supabaseUrl}/functions/v1/consumer-agent-spec?format=full`;
    
    const response = await fetch(specUrl, {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' }
    });
    
    if (!response.ok) {
      throw new Error(`Failed to fetch agent spec: ${response.status}`);
    }
    
    const spec = await response.json();
    cachedAgentSpec = spec;
    cacheTimestamp = now;
    return spec;
  } catch (error) {
    console.error('❌ Failed to fetch agent spec:', error);
    return getDefaultAgentSpec();
  }
}

function getDefaultAgentSpec(): any {
  return {
    persona: { name: "小智", role: "智能购物顾问", tone: "friendly" },
    system_prompt: `你是一个专业的手机销售顾问助手。`,
    intents: []
  };
}

function buildSystemPrompt(agentSpec: any, userInfo: any, catalog: any[], userContext?: string): string {
  const persona = agentSpec.persona || {};
  
  let systemPrompt = `# ${persona.name || '小智'} - ${persona.role || '智能购物顾问'}

## 用户信息
- 用户ID: ${userInfo.id}

## ⚠️⚠️⚠️ 最重要的规则 - 产品推荐格式 ⚠️⚠️⚠️

当推荐产品时，你**必须且只能**使用下面产品目录中的真实 product_id！

**可用产品目录（共${catalog.length}个）：**
${catalog.slice(0, 30).map(p => `• ID="${p.id}" | ${p.name} | ¥${p.price}`).join('\n')}

**在回复末尾必须包含：**
\`\`\`json
{
  "picks": [
    {"product_id": "从上面目录复制的真实ID", "note": "推荐理由"}
  ]
}
\`\`\`

**严格规则：**
1. product_id 必须从上面产品目录中复制，不要编造！
2. 如果目录中没有匹配的产品，返回空 picks: []
`;

  if (userContext) {
    systemPrompt += `\n## 用户历史偏好\n${userContext}\n`;
  }

  return systemPrompt;
}

// 解析文本响应中的 picks
function parsePicksFromText(text: string, catalog: any[]): Array<{ product_id: string; note: string }> {
  const picks: Array<{ product_id: string; note: string }> = [];
  const candidates: string[] = [];

  const addPick = (rawId?: string, note = '') => {
    if (!rawId) return;

    let matchedId = rawId;
    const hasExactMatch = catalog.some((item) => item.id === matchedId);

    if (!hasExactMatch) {
      const prefix = rawId.includes('...')
        ? rawId.replace('...', '')
        : rawId.length < 36
          ? rawId
          : '';

      if (prefix) {
        const matchedProduct = catalog.find((item) => item.id.startsWith(prefix));
        if (matchedProduct) {
          matchedId = matchedProduct.id;
        }
      }
    }

    const exists = catalog.some((item) => item.id === matchedId);
    if (exists && !picks.some((pick) => pick.product_id === matchedId)) {
      picks.push({ product_id: matchedId, note });
    }
  };

  const fencedMatch = text.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
  if (fencedMatch) candidates.push(fencedMatch[1]);

  const trimmed = text.trim();
  if (trimmed.startsWith('{')) candidates.push(trimmed);

  const picksArrayMatch = text.match(/"picks"\s*:\s*(\[[\s\S]*?\])/);
  if (picksArrayMatch) candidates.push(`{"picks":${picksArrayMatch[1]}}`);

  for (const candidate of candidates) {
    try {
      const parsed = JSON.parse(candidate);
      if (Array.isArray(parsed?.picks)) {
        for (const pick of parsed.picks) {
          addPick(pick?.product_id, pick?.note || '');
        }
        if (picks.length > 0) return picks;
      }
    } catch {
      // 继续尝试下一个候选
    }
  }

  const uuidRegex = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
  for (const matchedId of text.match(uuidRegex) || []) {
    addPick(matchedId);
  }

  return picks;
}

// 检测意图
function detectIntent(message: string, answer: string): string {
  const shoppingKeywords = ['买', '购', '推荐', '价格', '多少钱', '手机', '电脑'];
  const afterSalesKeywords = ['退货', '换货', '售后', '维修'];
  const compareKeywords = ['对比', '比较', '哪个更好'];
  
  if (compareKeywords.some(kw => message.includes(kw))) return 'COMPARE';
  if (shoppingKeywords.some(kw => message.includes(kw)) || answer.includes('picks')) return 'SHOPPING';
  if (afterSalesKeywords.some(kw => message.includes(kw))) return 'AFTERSALES';
  return 'GENERAL';
}

// ========================
// 记录测试结果
// ========================
async function recordTestResult(
  supabase: any,
  traceId: string,
  message: string,
  passed: boolean,
  issues: string[],
  responseSummary: any
) {
  try {
    await supabase.from('agent_test_results').insert({
      trace_id: traceId,
      agent_type: 'consumer',
      user_message: message,
      passed,
      issues,
      response_summary: responseSummary
    });
    console.log('📊 Test result recorded:', { traceId, passed, issuesCount: issues.length });
  } catch (error) {
    console.error('❌ Failed to record test result:', error);
  }
}

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  const traceId = req.headers.get('x-trace-id') || crypto.randomUUID();
  
  try {
    const body: CozeRequest = await req.json();
    const { message, conversationId, inputs } = body;
    
    console.log('📥 coze-chat-stream request:', {
      trace_id: traceId,
      message: message?.substring(0, 50),
      catalogCount: inputs?.catalog?.length || 0
    });

    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const supabaseKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
    const supabase = createClient(supabaseUrl, supabaseKey);

    let userInfo = { id: inputs.user_id || 'anonymous', email: '' };
    
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
    if (inputs.user_id && uuidRegex.test(inputs.user_id)) {
      const { data: userData } = await supabase.auth.admin.getUserById(inputs.user_id);
      if (userData?.user) {
        userInfo = { id: userData.user.id, email: userData.user.email || '' };
      }
    }

    let catalog = inputs.catalog || [];
    if (catalog.length === 0) {
      const { data: products } = await supabase
        .from('products')
        .select('id, name, price, stock_quantity, category, description')
        .eq('is_active', true)
        .limit(50);
      catalog = products || [];
    }

    const COZE_API_KEY = Deno.env.get('COZE_API_KEY') || Deno.env.get('COZE_API_TOKEN');
    const COZE_WORKFLOW_URL = Deno.env.get('COZE_WORKFLOW_URL') || 'https://dbwbtkkt9g.coze.site/stream_run';
    
    if (!COZE_API_KEY) {
      throw new Error('COZE_API_KEY not configured');
    }

    const agentSpec = await fetchAgentSpec();
    const systemPrompt = buildSystemPrompt(agentSpec, userInfo, catalog, inputs.user_context);
    
    const catalogSummary = catalog.slice(0, 20).map(p => 
      `[ID:${p.id}] ${p.name} ¥${p.price}`
    ).join('\n');
    
    const fullQuery = `${systemPrompt}

## 用户问题
${message}

## 可用产品（前20个）
${catalogSummary}`;

    // 调用 Coze API
    const cozeResponse = await fetch(COZE_WORKFLOW_URL, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${COZE_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ text: fullQuery }),
    });

    if (!cozeResponse.ok) {
      throw new Error(`Coze API error: ${cozeResponse.status}`);
    }

    // 创建 SSE 流
    const encoder = new TextEncoder();
    let fullAnswer = '';
    let rawResponseText = '';
    let usedFallback = false;
    
    const stream = new ReadableStream({
      async start(controller) {
        try {
          const reader = cozeResponse.body?.getReader();
          if (!reader) {
            throw new Error('No response body');
          }
          
          const decoder = new TextDecoder();
          let buffer = '';
          
          while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            
            const chunk = decoder.decode(value, { stream: true });
            buffer += chunk;
            rawResponseText += chunk;
            
            const lines = buffer.split('\n');
            buffer = lines.pop() || '';
            
            for (const line of lines) {
              if (!line.trim() || line.startsWith(':')) continue;
              
              let dataContent = line;
              if (line.startsWith('data:')) {
                dataContent = line.slice(5).trim();
              }
              
              if (!dataContent || dataContent === '[DONE]') continue;
              
              try {
                const parsed = JSON.parse(dataContent);
                const content = parsed.answer || 
                               parsed.content?.answer || 
                               parsed.data?.answer ||
                               parsed.choices?.[0]?.delta?.content ||
                               parsed.choices?.[0]?.message?.content ||
                               parsed.text ||
                               parsed.output ||
                               '';
                
                if (content) {
                  fullAnswer += content;
                  
                  const sseData = JSON.stringify({ 
                    type: 'text', 
                    content: content 
                  });
                  controller.enqueue(encoder.encode(`data: ${sseData}\n\n`));
                }
              } catch (e) {
                if (dataContent && !dataContent.startsWith('{') && !dataContent.startsWith('[')) {
                  console.log('📝 Non-JSON SSE content:', dataContent.substring(0, 50));
                }
              }
            }
          }
          
          // 处理剩余 buffer
          if (buffer.trim()) {
            try {
              const parsed = JSON.parse(buffer);
              const content = parsed.answer || parsed.content?.answer || parsed.data?.answer || '';
              if (content) {
                fullAnswer += content;
                const sseData = JSON.stringify({ type: 'text', content });
                controller.enqueue(encoder.encode(`data: ${sseData}\n\n`));
              }
            } catch (e) {}
          }
          
          // 备用解析
          if (!fullAnswer && rawResponseText) {
            console.log('⚠️ Stream parsing yielded no content, trying full response parse...');
            console.log('📄 Raw response (first 500 chars):', rawResponseText.substring(0, 500));
            
            for (const line of rawResponseText.split('\n')) {
              if (!line.trim()) continue;
              
              let jsonStr = line;
              if (line.startsWith('data:')) {
                jsonStr = line.slice(5).trim();
              }
              
              if (!jsonStr || jsonStr === '[DONE]') continue;
              
              try {
                const parsed = JSON.parse(jsonStr);
                const content = parsed.answer || 
                               parsed.content?.answer || 
                               parsed.data?.answer ||
                               parsed.output ||
                               parsed.text ||
                               '';
                if (content && content.length > fullAnswer.length) {
                  fullAnswer = content;
                }
              } catch {}
            }
            
            if (!fullAnswer) {
              try {
                const fullData = JSON.parse(rawResponseText);
                fullAnswer = fullData.answer || fullData.data?.answer || fullData.content?.answer || fullData.output || '';
              } catch {}
            }
            
            if (fullAnswer) {
              console.log('✅ Fallback parsing found content:', fullAnswer.length, 'chars');
              const sseData = JSON.stringify({ type: 'text', content: fullAnswer });
              controller.enqueue(encoder.encode(`data: ${sseData}\n\n`));
            }
          }
          
          // 最终备用：调用 Lovable AI
          if (!fullAnswer) {
            console.log('⚠️ Coze returned empty, falling back to Lovable AI...');
            usedFallback = true;
            
            const LOVABLE_API_KEY = Deno.env.get('LOVABLE_API_KEY');
            if (LOVABLE_API_KEY) {
              try {
                const lovableResponse = await fetch(_AI_CHAT_URL, {
                  method: 'POST',
                  headers: {
                    'Authorization': `Bearer ${_AI_CHAT_KEY}`,
                    'Content-Type': 'application/json',
                  },
                  body: JSON.stringify({
                    model: _mapAiModel('google/gemini-3-flash-preview'),
                    messages: [
                      { role: 'system', content: systemPrompt },
                      { role: 'user', content: message }
                    ],
                    max_tokens: 1000,
                  }),
                });
                
                if (lovableResponse.ok) {
                  const lovableData = await lovableResponse.json();
                  fullAnswer = lovableData.choices?.[0]?.message?.content || '';
                  
                  if (fullAnswer) {
                    console.log('✅ Lovable AI fallback success:', fullAnswer.length, 'chars');
                    const sseData = JSON.stringify({ type: 'text', content: fullAnswer });
                    controller.enqueue(encoder.encode(`data: ${sseData}\n\n`));
                  }
                }
              } catch (e) {
                console.error('❌ Lovable AI fallback failed:', e);
              }
            }
          }
          
          // 如果还是没有内容，发送友好错误
          if (!fullAnswer) {
            fullAnswer = '抱歉，AI助手暂时无法回复，请稍后再试。';
            const sseData = JSON.stringify({ type: 'text', content: fullAnswer });
            controller.enqueue(encoder.encode(`data: ${sseData}\n\n`));
          }
          
          // 解析 picks 和意图
          const picks = parsePicksFromText(fullAnswer, catalog);
          const intent = detectIntent(message, fullAnswer);
          
          // ========== 记录测试结果 ==========
          const testIssues: string[] = [];
          let testPassed = true;
          
          // 检查问题 1: Coze 是否返回了空回复
          if (usedFallback) {
            testIssues.push('ISSUE-002: Coze 返回空回复，触发了 Lovable AI 备用');
            testPassed = false;
          }
          
          // 检查问题 2: 购物意图但没有 picks
          if (intent === 'SHOPPING' && picks.length === 0) {
            testIssues.push('ISSUE-001: 购物意图但未返回有效的 picks');
            testPassed = false;
          }
          
          // 检查问题 3: 回复是否包含"无法回答"
          if (fullAnswer.includes('无法回答') || fullAnswer.includes('无法帮助')) {
            testIssues.push('ISSUE-002: 回复包含拒绝性语句');
            testPassed = false;
          }
          
          // 记录测试结果到数据库
          await recordTestResult(supabase, traceId, message, testPassed, testIssues, {
            answer_length: fullAnswer.length,
            picks_count: picks.length,
            intent,
            used_fallback: usedFallback,
            raw_response_preview: rawResponseText.substring(0, 200)
          });
          
          // 发送最终元数据
          const finalData = JSON.stringify({
            type: 'done',
            intent,
            picks,
            highlights: fullAnswer.split(/[。！？\n]/).filter(s => s.length > 10 && s.length < 100).slice(0, 3),
            meta: {
              platform: usedFallback ? 'lovable-fallback' : 'coze-stream',
              user: userInfo.id,
              catalog_count: catalog.length,
              probe_id: traceId,
              test_passed: testPassed,
              test_issues: testIssues
            },
            conversation_id: conversationId || ''
          });
          
          controller.enqueue(encoder.encode(`data: ${finalData}\n\n`));
          controller.enqueue(encoder.encode('data: [DONE]\n\n'));
          controller.close();
          
          console.log('✅ Stream completed:', { 
            answerLength: fullAnswer.length, 
            picksCount: picks.length,
            intent,
            testPassed,
            testIssues
          });
          
        } catch (error) {
          console.error('❌ Stream error:', error);
          const errorData = JSON.stringify({ 
            type: 'error', 
            message: (error instanceof Error ? error.message : '流式响应失败')
          });
          controller.enqueue(encoder.encode(`data: ${errorData}\n\n`));
          controller.close();
        }
      }
    });

    return new Response(stream, {
      headers: {
        ...corsHeaders,
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
      }
    });

  } catch (error) {
    console.error('❌ coze-chat-stream error:', error);
    
    return new Response(JSON.stringify({
      type: 'error',
      message: (error instanceof Error ? error.message : '未知错误')
    }), {
      status: 500,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' }
    });
  }
});
