import { useState, useCallback } from "react";
import { IWbw } from "./Wbw/WbwWord";
import { paliEndingGrammar, paliEndingType } from "../general/PaliEnding";
import { useIntl } from "react-intl";
import { useAppSelector } from "../../hooks";
import { siteInfo } from "../../reducers/layout";

// 类型定义
export interface WbwElement<T> {
  value: T;
  status: number;
}

interface StreamController {
  addData: (jsonlLine: string) => void;
  complete: () => void;
}

interface ProcessWbwStreamOptions {
  modelId: string;
  data: IWbw[];
  endingType: string[];
  endingGrammar: string[];
  onProgress?: (data: IWbw[], isComplete: boolean) => void;
  onComplete?: (finalData: IWbw[]) => void;
  onError?: (error: string) => void;
}

/**
 * 处理JSONL流式输出的函数
 */
export const processWbwStream = async ({
  modelId,
  data,
  endingType,
  endingGrammar,
  onProgress,
  onComplete,
  onError,
}: ProcessWbwStreamOptions): Promise<{
  success: boolean;
  data?: IWbw[];
  error?: string;
}> => {
  if (typeof process.env.REACT_APP_OPENAI_PROXY === "undefined") {
    console.error("no REACT_APP_OPENAI_PROXY");
    const error = "API配置错误";
    onError?.(error);
    return { success: false, error };
  }
  const sys_prompt = `
  你是一个巴利语专家。用户提供的jsonl 数据 是巴利文句子的全部单词
请根据每个单词的拼写 real.value 填写如下字段
巴利单词的词典原型：parent.value  
单词的中文意思：meaning.value
巴利单词的拆分：factors.value  
语尾请加[]
拆分后每个组成部分的中文意思factorMeaning.value
请按照下表填写巴利语单词的类型 type.value
\`\`\`csv
${endingType.join("\n")}
\`\`\`

请按照下表填写巴利语单词的语法信息 grammar.value
名词和形容词填写 性,数,格
动词填写 人称,数,时态语气
用 $ 作为分隔符
\`\`\`csv
${endingGrammar.join("\n")}
\`\`\`
 直接输出JSONL格式数据
`;

  const jsonl = data.map((obj) => JSON.stringify(obj)).join("\n");
  const prompt = `
\`\`\`jsonl
${jsonl}
\`\`\`
`;
  console.debug("ai wbw system prompt", sys_prompt, prompt);
  try {
    const payload = {
      model: "grok-3", // 或者从models数组中获取实际模型名称
      messages: [
        {
          role: "system",
          content: sys_prompt,
        },
        { role: "user", content: prompt },
      ],
      stream: true,
      temperature: 0.3,
      max_tokens: 4000,
    };

    const url = process.env.REACT_APP_OPENAI_PROXY;
    const requestData = {
      model_id: modelId,
      payload: payload,
    };

    console.info("api request", url, requestData);

    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer AIzaSyCzr8KqEdaQ3cRCxsFwSHh8c7kF3RZTZWw`,
      },
      body: JSON.stringify(requestData),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const reader = response.body?.getReader();
    if (!reader) {
      throw new Error("无法获取响应流");
    }

    const decoder = new TextDecoder();
    let buffer = "";
    let jsonlBuffer = ""; // 用于累积JSONL内容
    const resultData: IWbw[] = [];

    // 创建流控制器
    const streamController: StreamController = {
      addData: (jsonlLine: string) => {
        try {
          // 解析JSONL行
          const parsedData = JSON.parse(jsonlLine.trim());
          console.info("ai wbw stream ok", parsedData);
          // 转换为IWbw格式
          const wbwData: IWbw = {
            book: parsedData.book || 0,
            para: parsedData.para || 0,
            sn: parsedData.sn || [],
            word: parsedData.word || { value: "", status: 0 },
            real: parsedData.real || { value: null, status: 0 },
            meaning: parsedData.meaning,
            type: parsedData.type,
            grammar: parsedData.grammar,
            style: parsedData.style,
            case: parsedData.case,
            parent: parsedData.parent,
            parent2: parsedData.parent2,
            grammar2: parsedData.grammar2,
            factors: parsedData.factors,
            factorMeaning: parsedData.factorMeaning,
            relation: parsedData.relation,
            note: parsedData.note,
            bookMarkColor: parsedData.bookMarkColor,
            bookMarkText: parsedData.bookMarkText,
            locked: parsedData.locked || false,
            confidence: parsedData.confidence || 0.5,
            attachments: parsedData.attachments,
            hasComment: parsedData.hasComment,
            grammarId: parsedData.grammarId,
            bookName: parsedData.bookName,
            editor: parsedData.editor,
            created_at: parsedData.created_at,
            updated_at: parsedData.updated_at,
          };

          resultData.push(wbwData);

          // 调用进度回调
          onProgress?.(resultData, false);
        } catch (e) {
          console.warn("解析JSONL行失败:", e, "内容:", jsonlLine);
        }
      },
      complete: () => {
        onProgress?.(resultData, true);
        onComplete?.(resultData);
      },
    };

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

        if (done) {
          // 处理最后的缓冲内容
          if (jsonlBuffer.trim()) {
            const lines = jsonlBuffer.trim().split("\n");
            for (const line of lines) {
              if (line.trim()) {
                streamController.addData(line);
              }
            }
          }
          streamController.complete();
          return { success: true, data: resultData };
        }

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

        for (const line of lines) {
          if (line.trim() === "") continue;

          if (line.startsWith("data: ")) {
            const data = line.slice(6);

            if (data === "[DONE]") {
              // 处理剩余的JSONL内容
              if (jsonlBuffer.trim()) {
                const jsonlLines = jsonlBuffer.trim().split("\n");
                for (const jsonlLine of jsonlLines) {
                  if (jsonlLine.trim()) {
                    streamController.addData(jsonlLine);
                  }
                }
              }
              streamController.complete();
              return { success: true, data: resultData };
            }

            try {
              const parsed = JSON.parse(data);
              const delta = parsed.choices?.[0]?.delta;

              if (delta?.content) {
                // 累积内容到JSONL缓冲区
                jsonlBuffer += delta.content;

                // 检查是否有完整的JSONL行
                const jsonlLines = jsonlBuffer.split("\n");

                // 保留最后一行（可能不完整）
                jsonlBuffer = jsonlLines.pop() || "";

                // 处理完整的行
                for (const jsonlLine of jsonlLines) {
                  if (jsonlLine.trim()) {
                    streamController.addData(jsonlLine);
                  }
                }
              }
            } catch (e) {
              console.warn("解析SSE数据失败:", e);
            }
          }
        }
      }
    } catch (error) {
      console.error("读取流数据失败:", error);
      const errorMessage = "读取响应流失败";
      onError?.(errorMessage);
      return { success: false, error: errorMessage };
    }
  } catch (error) {
    console.error("API调用失败:", error);
    const errorMessage = "API调用失败，请重试";
    onError?.(errorMessage);
    return { success: false, error: errorMessage };
  }
};

/**
 * React Hook 用法示例
 */
export const useWbwStreamProcessor = () => {
  const [isProcessing, setIsProcessing] = useState<boolean>(false);
  const [wbwData, setWbwData] = useState<IWbw[]>([]);
  const [error, setError] = useState<string>();

  const intl = useIntl(); // 在Hook中使用

  const endingType = paliEndingType.map((item) => {
    return (
      intl.formatMessage({ id: `dict.fields.type.${item}.label` }) +
      `:.${item}.`
    );
  });

  const endingGrammar = paliEndingGrammar.map((item) => {
    return (
      intl.formatMessage({ id: `dict.fields.type.${item}.label` }) +
      `:.${item}.`
    );
  });

  const processStream = useCallback(
    async (modelId: string, data: IWbw[]) => {
      setIsProcessing(true);
      setWbwData([]);
      setError(undefined);

      const result = await processWbwStream({
        modelId,
        data,
        endingType,
        endingGrammar,
        onProgress: (data, isComplete) => {
          console.info("onProgress", data);
          setWbwData([...data]); // 创建新数组触发重渲染
        },
        onComplete: (finalData) => {
          setWbwData(finalData);
          setIsProcessing(false);
        },
        onError: (errorMessage) => {
          setError(errorMessage);
          setIsProcessing(false);
        },
      });

      if (!result.success) {
        setError(result.error || "处理失败");
        setIsProcessing(false);
      }

      return result;
    },
    [endingGrammar, endingType]
  );

  return {
    processStream,
    isProcessing,
    wbwData,
    error,
    clearData: useCallback(() => {
      setWbwData([]);
      setError(undefined);
    }, []),
  };
};
