import { apiClient } from './apiClient';

export interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
}

export interface ChatSource {
  fileName: string;
  title?: string;
  content: string;
  score: number;
  chunkIndex: number;
  fileId?: string;
}

// New types for streaming chat responses
export type ChatStreamType = 
  | 'history'      // 上文：历史对话内容
  | 'sources'      // 引用：搜索结果来源
  | 'content'      // 正文：AI生成的回答
  | 'thinking'     // 深度思考：推理过程
  | 'status'       // 状态：搜索进度、调试信息
  | 'historyId'    // 历史ID：聊天会话ID
  | 'error';       // 错误

export interface ChatStreamChunk {
  type: ChatStreamType;
  data: any;
}

export interface HistoryData {
  messages: ChatMessage[];
}

export interface StatusData {
  stage: 'searching' | 'search_complete' | 'generating' | 'debug';
  message: string;
  details?: any;
}

export class ChatService {
  async *streamChat(
    message: string,
    history: ChatMessage[],
    authToken: string,
    userLanguage: string = 'ja',
    selectedEmbeddingId?: string,
    selectedLLMId?: string, // 追加: 選択された LLM ID
    selectedGroups?: string[], // 追加: 選択されたグループ
    selectedFiles?: string[], // 追加: 選択されたファイル
    historyId?: string, // 追加: 会話履歴 ID
    enableRerank?: boolean, // 追加: Rerank を有効にする
    selectedRerankId?: string, // 追加: Rerank モデル ID
    temperature?: number, // 追加: temperature パラメータ
    maxTokens?: number, // 追加: maxTokens パラメータ
    topK?: number, // 追加: topK パラメータ
    similarityThreshold?: number, // 追加: similarityThreshold パラメータ
    rerankSimilarityThreshold?: number, // 追加: rerankSimilarityThreshold パラメータ
    enableQueryExpansion?: boolean, // 追加
    enableHyDE?: boolean // 追加
  ): AsyncGenerator<ChatStreamChunk> {
    try {
      const response = await apiClient.request('/chat/stream', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-user-language': userLanguage || localStorage.getItem('userLanguage') || 'ja',
        },
        body: JSON.stringify({
          message,
          history,
          userLanguage,
          selectedEmbeddingId,
          selectedLLMId,
          selectedGroups,
          selectedFiles,
          historyId,
          enableRerank,
          selectedRerankId,
          temperature,
          maxTokens,
          topK,
          similarityThreshold,
          rerankSimilarityThreshold,
          enableQueryExpansion,
          enableHyDE
        }),
      });

      if (!response.ok) {
        let errorMessage = 'Request failed';
        try {
          const error = await response.json();
          errorMessage = error.error || error.message || 'Request failed';
        } catch {
          errorMessage = `Server error: ${response.status}`;
        }
        yield { type: 'error', data: errorMessage };
        return;
      }

      const reader = response.body?.getReader();
      if (!reader) {
        yield { type: 'error', data: 'レスポンスストリームを読み取れません' };
        return;
      }

      const decoder = new TextDecoder();
      let buffer = '';

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

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

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            if (data === '[DONE]') {
              return;
            }

            try {
              const parsed = JSON.parse(data);
              yield parsed;
            } catch (e) {
              console.warn('Failed to parse SSE data:', data);
            }
          }
        }
      }
    } catch (error: any) {
      yield { type: 'error', data: error.message || 'Network error' };
    }
  }

  async *streamAssist(
    instruction: string,
    context: string,
    authToken: string
  ): AsyncGenerator<{ type: 'content' | 'error'; data: any }> {
    try {
      const response = await apiClient.request('/chat/assist', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-user-language': localStorage.getItem('userLanguage') || 'ja',
        },
        body: JSON.stringify({ instruction, context }),
      });

      if (!response.ok) {
        yield { type: 'error', data: 'Request failed' };
        return;
      }

      const reader = response.body?.getReader();
      if (!reader) return;

      const decoder = new TextDecoder();
      let buffer = '';

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

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

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            if (data === '[DONE]') return;
            try {
              yield JSON.parse(data);
            } catch (e) { console.warn(e) }
          }
        }
      }
    } catch (error: any) {
      yield { type: 'error', data: error.message };
    }
  }
}

export const chatService = new ChatService();