/**
 * Dify 流式响应客户端
 * 支持 SSE 流式输出，实时显示 AI 回复
 * 与 cozeStreamClient 保持相同的接口
 */

import { supabase } from '@/integrations/supabase/client';
import type { CozeStreamCallbacks } from '@/utils/cozeStreamClient';
import { generateUUID } from '@/utils/idGenerator';

interface DifyStreamOptions {
  message: string;
  userId: string;
  conversationId?: string;
  localConversationId?: string;   // ★ 本地 conversations 表的主键 UUID（用于加载历史）
  userContext?: string;
  catalog?: Array<{
    id: string;
    name: string;
    price: number;
    stock_quantity?: number;
    category?: string;
    description?: string;
  }>;
}

/**
 * 调用 Dify 流式 API
 * 接口与 streamCozeChat 完全一致，方便切换
 */
export async function streamDifyChat(
  options: DifyStreamOptions,
  callbacks: CozeStreamCallbacks
): Promise<void> {
  const traceId = generateUUID();

  const { data: { session } } = await supabase.auth.getSession();
  
  const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL;
  const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;

  const requestBody = {
    message: options.message,
    conversationId: options.conversationId || '',
    localConversationId: options.localConversationId || '',
    inputs: {
      user_id: options.userId || 'guest',
      trace_id: traceId,
      user_context: options.userContext || '',
      catalog: options.catalog || [],
    },
  };

  try {
    console.log('🚀 [DIFY STREAM] 开始流式调用');

    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 65000);

    const response = await fetch(`${SUPABASE_URL}/functions/v1/dify-chat-stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${session?.access_token || SUPABASE_ANON_KEY}`,
        'X-Trace-Id': traceId,
        'X-User-Id': options.userId || 'guest',
      },
      body: JSON.stringify(requestBody),
      signal: controller.signal,
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Dify 请求失败 (${response.status}): ${errorText}`);
    }

    if (!response.body) {
      throw new Error('响应体为空');
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';

    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        if (buffer.trim()) {
          await processSSELine(buffer, callbacks);
        }
        break;
      }

      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split('\n');
      buffer = lines.pop() || '';

      for (const line of lines) {
        await processSSELine(line, callbacks);
      }
    }

    console.log('✅ [DIFY STREAM] 流式调用完成');
  } catch (error) {
    console.error('❌ [DIFY STREAM] 错误:', error);
    if (error instanceof DOMException && error.name === 'AbortError') {
      callbacks.onError('AI响应超时（65秒），请重新发送消息');
    } else {
      callbacks.onError(error instanceof Error ? error.message : '流式请求失败');
    }
  }
}

async function processSSELine(line: string, callbacks: CozeStreamCallbacks) {
  const trimmedLine = line.trim();
  if (!trimmedLine || trimmedLine.startsWith(':')) return;
  if (trimmedLine === 'data: [DONE]') return;

  if (trimmedLine.startsWith('data:')) {
    const jsonStr = trimmedLine.slice(5).trim();
    try {
      const event = JSON.parse(jsonStr);
      switch (event.type) {
        case 'text':
          callbacks.onText(event.content);
          break;
        case 'done':
          console.log('📦 [DIFY STREAM] done event:', {
            intent: event.intent,
            picksCount: event.picks?.length || 0,
            picksPreview: event.picks?.slice(0, 3).map((p: any) => p.product_id?.substring(0, 12) + '...'),
            hasAction: !!event.action,
            action: event.action,
            hasComponents: !!(event.components?.length),
            componentsCount: event.components?.length || 0,
            meta: event.meta,
          });
          await callbacks.onDone(event);
          break;
        case 'error':
          callbacks.onError(event.message);
          break;
      }
    } catch (e) {
      // JSON.parse SyntaxError or callback rejection — safe fallback
      if (jsonStr && !jsonStr.startsWith('{')) {
        try {
          callbacks.onText(jsonStr);
        } catch {
          // onText itself failed; nothing more we can do
        }
      }
    }
  }
}
