import React, { useCallback, useContext, useEffect, useState, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import { UserContext } from '../../context/User/index.js';
import {
  API,
  getUserIdFromLocalStorage,
  showError,
  getLogo,
} from '../../helpers/index.js';
import {
  Card,
  Chat,
  Input,
  Layout,
  Select,
  Slider,
  TextArea,
  Typography,
  Button,
  Tag,
  Tabs,
  TabPane,
  Toast,
  Tooltip,
  Modal,
} from '@douyinfe/semi-ui';
import { SSE } from 'sse';
import {
  Settings,
  Sparkles,
  ChevronRight,
  ChevronUp,
  Brain,
  Zap,
  MessageSquare,
  SlidersHorizontal,
  Hash,
  Thermometer,
  Type,
  Users,
  Loader2,
  Target,
  Repeat,
  Ban,
  Shuffle,
  ToggleLeft,
  Code,
  Eye,
  EyeOff,
  FileText,
  Clock,
  Check,
  X,
  Copy,
  RefreshCw,
  Trash2,
} from 'lucide-react';
import { StyleContext } from '../../context/Style/index.js';
import { useTranslation } from 'react-i18next';
import { renderGroupOption, truncateText, stringToColor } from '../../helpers/render.js';
import { IconSend } from '@douyinfe/semi-icons';

let id = 4;
function getId() {
  return `${id++}`;
}

const generateAvatarDataUrl = (username) => {
  if (!username) {
    return 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png';
  }
  const firstLetter = username[0].toUpperCase();
  const bgColor = stringToColor(username);
  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
      <circle cx="16" cy="16" r="16" fill="${bgColor}" />
      <text x="50%" y="50%" dominant-baseline="central" text-anchor="middle" font-size="16" fill="#ffffff" font-family="sans-serif">${firstLetter}</text>
    </svg>
  `;
  return `data:image/svg+xml;base64,${btoa(svg)}`;
};

const Playground = () => {
  const { t } = useTranslation();
  const [userState, userDispatch] = useContext(UserContext);

  const roleInfo = {
    user: {
      name: userState?.user?.username || 'User',
      avatar: generateAvatarDataUrl(userState?.user?.username),
    },
    assistant: {
      name: 'Assistant',
      avatar: getLogo(),
    },
    system: {
      name: 'System',
      avatar:
        'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/other/logo.png',
    },
  };

  const defaultMessage = [
    {
      role: 'user',
      id: '2',
      createAt: 1715676751919,
      content: t('你好'),
    },
    {
      role: 'assistant',
      id: '3',
      createAt: 1715676751919,
      content: t('你好，请问有什么可以帮助您的吗？'),
      reasoningContent: '',
      isReasoningExpanded: false,
    },
  ];

  const defaultModel = 'deepseek-r1';
  const [inputs, setInputs] = useState({
    model: defaultModel,
    group: '',
    max_tokens: 0,
    temperature: 0,
    top_p: 1,
    frequency_penalty: 0,
    presence_penalty: 0,
    seed: null,
    stream: true,
  });
  const [parameterEnabled, setParameterEnabled] = useState({
    max_tokens: true,
    temperature: true,
    top_p: false,
    frequency_penalty: false,
    presence_penalty: false,
    seed: false,
  });
  const [searchParams, setSearchParams] = useSearchParams();
  const [status, setStatus] = useState({});
  const [systemPrompt, setSystemPrompt] = useState(
    'You are a helpful assistant. You can help me by answering my questions. You can also ask me questions.',
  );
  const [message, setMessage] = useState(defaultMessage);
  const [models, setModels] = useState([]);
  const [groups, setGroups] = useState([]);
  const [showSettings, setShowSettings] = useState(true);
  const [showDebugPanel, setShowDebugPanel] = useState(true);
  const [debugData, setDebugData] = useState({
    request: null,
    response: null,
    timestamp: null
  });
  const [activeDebugTab, setActiveDebugTab] = useState('request');
  const [styleState, styleDispatch] = useContext(StyleContext);
  const sseSourceRef = useRef(null);

  const handleInputChange = (name, value) => {
    setInputs((inputs) => ({ ...inputs, [name]: value }));
  };

  const handleParameterToggle = (paramName) => {
    setParameterEnabled(prev => ({
      ...prev,
      [paramName]: !prev[paramName]
    }));
  };

  useEffect(() => {
    if (searchParams.get('expired')) {
      showError(t('未登录或登录已过期，请重新登录！'));
    }
    let status = localStorage.getItem('status');
    if (status) {
      status = JSON.parse(status);
      setStatus(status);
    }
    loadModels();
    loadGroups();
  }, [searchParams, t]);

  const loadModels = async () => {
    let res = await API.get(`/api/user/models`);
    const { success, message, data } = res.data;
    if (success) {
      let localModelOptions = data.map((model) => ({
        label: model,
        value: model,
      }));
      setModels(localModelOptions);
      const hasDefault = localModelOptions.some(option => option.value === defaultModel);
      if (!hasDefault && localModelOptions.length > 0) {
        setInputs((inputs) => ({ ...inputs, model: localModelOptions[0].value }));
      }
    } else {
      showError(t(message));
    }
  };

  const loadGroups = async () => {
    let res = await API.get(`/api/user/self/groups`);
    const { success, message, data } = res.data;
    if (success) {
      let localGroupOptions = Object.entries(data).map(([group, info]) => ({
        label: truncateText(info.desc, '50%'),
        value: group,
        ratio: info.ratio,
        fullLabel: info.desc,
      }));

      if (localGroupOptions.length === 0) {
        localGroupOptions = [
          {
            label: t('用户分组'),
            value: '',
            ratio: 1,
          },
        ];
      } else {
        const localUser = JSON.parse(localStorage.getItem('user'));
        const userGroup =
          (userState.user && userState.user.group) ||
          (localUser && localUser.group);

        if (userGroup) {
          const userGroupIndex = localGroupOptions.findIndex(
            (g) => g.value === userGroup,
          );
          if (userGroupIndex > -1) {
            const userGroupOption = localGroupOptions.splice(
              userGroupIndex,
              1,
            )[0];
            localGroupOptions.unshift(userGroupOption);
          }
        }
      }

      setGroups(localGroupOptions);
      handleInputChange('group', localGroupOptions[0].value);
    } else {
      showError(t(message));
    }
  };

  const getSystemMessage = () => {
    if (systemPrompt !== '') {
      return {
        role: 'system',
        id: '1',
        createAt: 1715676751919,
        content: systemPrompt,
      };
    }
  };

  let handleNonStreamRequest = async (payload) => {
    setDebugData(prev => ({
      ...prev,
      request: payload,
      timestamp: new Date().toISOString(),
      response: null
    }));
    setActiveDebugTab('request');

    try {
      const response = await fetch('/pg/chat/completions', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'New-Api-User': getUserIdFromLocalStorage(),
        },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        let errorBody = '';
        try {
          errorBody = await response.text();
        } catch (e) {
          errorBody = '无法读取错误响应体';
        }

        const errorInfo = {
          error: 'HTTP错误',
          status: response.status,
          statusText: response.statusText,
          body: errorBody,
          timestamp: new Date().toISOString()
        };

        setDebugData(prev => ({
          ...prev,
          response: JSON.stringify(errorInfo, null, 2)
        }));
        setActiveDebugTab('response');

        throw new Error(`HTTP error! status: ${response.status}, body: ${errorBody}`);
      }

      const data = await response.json();

      setDebugData(prev => ({
        ...prev,
        response: JSON.stringify(data, null, 2)
      }));
      setActiveDebugTab('response');

      if (data.choices && data.choices[0]) {
        const choice = data.choices[0];
        let content = choice.message?.content || '';
        let reasoningContent = choice.message?.reasoning_content || '';

        setMessage((prevMessage) => {
          const newMessages = [...prevMessage];
          const lastMessage = newMessages[newMessages.length - 1];
          if (lastMessage && lastMessage.status === 'loading') {
            newMessages[newMessages.length - 1] = {
              ...lastMessage,
              content: content,
              reasoningContent: reasoningContent,
              status: 'complete',
              isReasoningExpanded: false
            };
          }
          return newMessages;
        });
      }
    } catch (error) {
      console.error('Non-stream request error:', error);

      const errorInfo = {
        error: '非流式请求错误',
        message: error.message,
        timestamp: new Date().toISOString(),
        stack: error.stack
      };

      if (error.message.includes('HTTP error')) {
        errorInfo.details = '服务器返回了错误状态码';
      } else if (error.message.includes('Failed to fetch')) {
        errorInfo.details = '网络连接失败或服务器无响应';
      }

      setDebugData(prev => ({
        ...prev,
        response: JSON.stringify(errorInfo, null, 2)
      }));
      setActiveDebugTab('response');

      setMessage((prevMessage) => {
        const newMessages = [...prevMessage];
        const lastMessage = newMessages[newMessages.length - 1];
        if (lastMessage && lastMessage.status === 'loading') {
          newMessages[newMessages.length - 1] = {
            ...lastMessage,
            content: t('请求发生错误: ') + error.message,
            status: 'error',
            isReasoningExpanded: false
          };
        }
        return newMessages;
      });
    }
  };

  let handleSSE = (payload) => {
    setDebugData(prev => ({
      ...prev,
      request: payload,
      timestamp: new Date().toISOString(),
      response: null
    }));
    setActiveDebugTab('request');

    let source = new SSE('/pg/chat/completions', {
      headers: {
        'Content-Type': 'application/json',
        'New-Api-User': getUserIdFromLocalStorage(),
      },
      method: 'POST',
      payload: JSON.stringify(payload),
    });

    sseSourceRef.current = source;

    let responseData = '';
    let hasReceivedFirstResponse = false;

    source.addEventListener('message', (e) => {
      if (e.data === '[DONE]') {
        source.close();
        sseSourceRef.current = null;
        setDebugData(prev => ({
          ...prev,
          response: responseData
        }));
        completeMessage();
        return;
      }

      try {
        let payload = JSON.parse(e.data);
        responseData += e.data + '\n';

        if (!hasReceivedFirstResponse) {
          setActiveDebugTab('response');
          hasReceivedFirstResponse = true;
        }

        const delta = payload.choices?.[0]?.delta;
        if (delta) {
          if (delta.reasoning_content) {
            streamMessageUpdate(delta.reasoning_content, 'reasoning');
          }
          if (delta.content) {
            streamMessageUpdate(delta.content, 'content');
          }
        }
      } catch (error) {
        console.error('Failed to parse SSE message:', error);
        const errorInfo = `解析错误: ${error.message}`;

        setDebugData(prev => ({
          ...prev,
          response: responseData + `\n\nError: ${errorInfo}`
        }));
        setActiveDebugTab('response');

        streamMessageUpdate(t('解析响应数据时发生错误'), 'content');
        completeMessage('error');
      }
    });

    source.addEventListener('error', (e) => {
      console.error('SSE Error:', e);
      const errorMessage = e.data || t('请求发生错误');

      const errorInfo = {
        error: 'SSE连接错误',
        message: errorMessage,
        status: source.status,
        readyState: source.readyState,
        timestamp: new Date().toISOString()
      };

      setDebugData(prev => ({
        ...prev,
        response: responseData + '\n\nSSE Error:\n' + JSON.stringify(errorInfo, null, 2)
      }));
      setActiveDebugTab('response');

      streamMessageUpdate(errorMessage, 'content');
      completeMessage('error');
      sseSourceRef.current = null;
      source.close();
    });

    source.addEventListener('readystatechange', (e) => {
      if (e.readyState >= 2) {
        if (source.status !== undefined && source.status !== 200) {
          const errorInfo = {
            error: 'HTTP状态错误',
            status: source.status,
            readyState: source.readyState,
            timestamp: new Date().toISOString()
          };

          setDebugData(prev => ({
            ...prev,
            response: responseData + '\n\nHTTP Error:\n' + JSON.stringify(errorInfo, null, 2)
          }));
          setActiveDebugTab('response');

          source.close();
          streamMessageUpdate(t('连接已断开'), 'content');
          completeMessage('error');
        }
      }
    });

    try {
      source.stream();
    } catch (error) {
      console.error('Failed to start SSE stream:', error);
      const errorInfo = {
        error: '启动SSE流失败',
        message: error.message,
        timestamp: new Date().toISOString()
      };

      setDebugData(prev => ({
        ...prev,
        response: 'Stream启动失败:\n' + JSON.stringify(errorInfo, null, 2)
      }));
      setActiveDebugTab('response');

      streamMessageUpdate(t('建立连接时发生错误'), 'content');
      completeMessage('error');
    }
  };

  const onMessageSend = useCallback(
    (content, attachment) => {
      console.log('attachment: ', attachment);
      setMessage((prevMessage) => {
        const newMessage = [
          ...prevMessage,
          {
            role: 'user',
            content: content,
            createAt: Date.now(),
            id: getId(),
          },
        ];

        const getPayload = () => {
          let systemMessage = getSystemMessage();
          let messages = newMessage.map((item) => {
            return {
              role: item.role,
              content: item.content,
            };
          });
          if (systemMessage) {
            messages.unshift(systemMessage);
          }
          const payload = {
            messages: messages,
            stream: inputs.stream,
            model: inputs.model,
            group: inputs.group,
          };

          if (parameterEnabled.max_tokens && inputs.max_tokens > 0) {
            payload.max_tokens = parseInt(inputs.max_tokens);
          }
          if (parameterEnabled.temperature) {
            payload.temperature = inputs.temperature;
          }
          if (parameterEnabled.top_p) {
            payload.top_p = inputs.top_p;
          }
          if (parameterEnabled.frequency_penalty) {
            payload.frequency_penalty = inputs.frequency_penalty;
          }
          if (parameterEnabled.presence_penalty) {
            payload.presence_penalty = inputs.presence_penalty;
          }
          if (parameterEnabled.seed && inputs.seed !== null && inputs.seed !== '') {
            payload.seed = parseInt(inputs.seed);
          }

          return payload;
        };

        const payload = getPayload();

        if (inputs.stream) {
          handleSSE(payload);
        } else {
          handleNonStreamRequest(payload);
        }

        newMessage.push({
          role: 'assistant',
          content: '',
          reasoningContent: '',
          isReasoningExpanded: true,
          createAt: Date.now(),
          id: getId(),
          status: 'loading',
        });
        return newMessage;
      });
    },
    [getSystemMessage, inputs, setMessage],
  );

  const completeMessage = useCallback((status = 'complete') => {
    setMessage((prevMessage) => {
      const lastMessage = prevMessage[prevMessage.length - 1];
      if (lastMessage.status === 'complete' || lastMessage.status === 'error') {
        return prevMessage;
      }
      return [...prevMessage.slice(0, -1), { ...lastMessage, status: status, isReasoningExpanded: false }];
    });
  }, [setMessage]);

  const streamMessageUpdate = useCallback((textChunk, type) => {
    setMessage((prevMessage) => {
      const lastMessage = prevMessage[prevMessage.length - 1];
      let newMessage = { ...lastMessage };

      if (lastMessage.status === 'error') {
        return prevMessage;
      }

      if (lastMessage.status === 'loading' || lastMessage.status === 'incomplete') {
        if (type === 'reasoning') {
          newMessage = {
            ...newMessage,
            reasoningContent: (lastMessage.reasoningContent || '') + textChunk,
            status: 'incomplete',
          };
        } else if (type === 'content') {
          const newContent = (lastMessage.content || '') + textChunk;

          newMessage = {
            ...newMessage,
            content: newContent,
            status: 'incomplete',
            isReasoningExpanded: lastMessage.isReasoningExpanded,
          };
        }
      }
      return [...prevMessage.slice(0, -1), newMessage];
    });
  }, [setMessage]);

  const handleMessageCopy = useCallback((message) => {
    if (!message.content) return;

    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(message.content).then(() => {
        Toast.success({
          content: t('消息已复制到剪贴板'),
          duration: 2,
        });
      }).catch(err => {
        console.error('Clipboard API 复制失败:', err);
        fallbackCopyToClipboard(message.content);
      });
    } else {
      fallbackCopyToClipboard(message.content);
    }
  }, [t]);

  const fallbackCopyToClipboard = useCallback((text) => {
    try {
      if (!document.execCommand) {
        throw new Error('execCommand not supported');
      }

      const textArea = document.createElement('textarea');
      textArea.value = text;

      textArea.style.position = 'fixed';
      textArea.style.top = '-9999px';
      textArea.style.left = '-9999px';
      textArea.style.opacity = '0';
      textArea.style.pointerEvents = 'none';
      textArea.style.zIndex = '-1';
      textArea.setAttribute('readonly', '');

      document.body.appendChild(textArea);

      if (textArea.select) {
        textArea.select();
      }
      if (textArea.setSelectionRange) {
        textArea.setSelectionRange(0, text.length);
      }

      const successful = document.execCommand('copy');
      document.body.removeChild(textArea);

      if (successful) {
        Toast.success({
          content: t('消息已复制到剪贴板'),
          duration: 2,
        });
      } else {
        throw new Error('execCommand copy failed');
      }
    } catch (err) {
      console.error('回退复制方案也失败:', err);

      let errorMessage = t('复制失败，请手动选择文本复制');

      if (window.location.protocol === 'http:' && window.location.hostname !== 'localhost') {
        errorMessage = t('复制功能需要 HTTPS 环境，请手动复制');
      } else if (!navigator.clipboard && !document.execCommand) {
        errorMessage = t('浏览器不支持复制功能，请手动复制');
      }

      Toast.error({
        content: errorMessage,
        duration: 4,
      });
    }
  }, [t]);

  const handleMessageReset = useCallback((targetMessage) => {
    setMessage(prevMessages => {
      const messageIndex = prevMessages.findIndex(msg => msg.id === targetMessage.id);
      if (messageIndex === -1) return prevMessages;

      if (targetMessage.role === 'user') {
        const newMessages = prevMessages.slice(0, messageIndex);
        setTimeout(() => {
          onMessageSend(targetMessage.content);
        }, 100);
        return newMessages;
      } else if (targetMessage.role === 'assistant') {
        let userMessageIndex = messageIndex - 1;
        while (userMessageIndex >= 0 && prevMessages[userMessageIndex].role !== 'user') {
          userMessageIndex--;
        }
        if (userMessageIndex >= 0) {
          const userMessage = prevMessages[userMessageIndex];
          const newMessages = prevMessages.slice(0, userMessageIndex);
          setTimeout(() => {
            onMessageSend(userMessage.content);
          }, 100);
          return newMessages;
        }
      }
      return prevMessages;
    });
  }, [onMessageSend]);

  const handleMessageDelete = useCallback((targetMessage) => {
    Modal.confirm({
      title: t('确认删除'),
      content: t('确定要删除这条消息吗？'),
      okText: t('确定'),
      cancelText: t('取消'),
      okButtonProps: {
        type: 'danger',
      },
      onOk: () => {
        setMessage(prevMessages => {
          const messageIndex = prevMessages.findIndex(msg => msg.id === targetMessage.id);
          if (messageIndex === -1) return prevMessages;

          if (targetMessage.role === 'user' && messageIndex < prevMessages.length - 1) {
            const nextMessage = prevMessages[messageIndex + 1];
            if (nextMessage.role === 'assistant') {
              Toast.success({
                content: t('已删除消息及其回复'),
                duration: 2,
              });
              return prevMessages.filter((_, index) => index !== messageIndex && index !== messageIndex + 1);
            }
          }

          Toast.success({
            content: t('消息已删除'),
            duration: 2,
          });
          return prevMessages.filter(msg => msg.id !== targetMessage.id);
        });
      },
    });
  }, [setMessage, t]);

  const onStopGenerator = useCallback(() => {
    if (sseSourceRef.current) {
      sseSourceRef.current.close();
      sseSourceRef.current = null;
      setMessage((prevMessage) => {
        const lastMessage = prevMessage[prevMessage.length - 1];
        if (lastMessage.status === 'loading' || lastMessage.status === 'incomplete') {
          return [...prevMessage.slice(0, -1), {
            ...lastMessage,
            status: 'complete',
            isReasoningExpanded: false
          }];
        }
        return prevMessage;
      });
    }
  }, [setMessage]);

  const DebugToggle = () => {
    return (
      <Button
        icon={showDebugPanel ? <EyeOff size={14} /> : <Eye size={14} />}
        onClick={() => setShowDebugPanel(!showDebugPanel)}
        theme="borderless"
        type="tertiary"
        size="small"
        className="!rounded-lg !text-gray-600 hover:!text-purple-600 hover:!bg-purple-50"
      >
        {showDebugPanel ? t('隐藏调试') : t('显示调试')}
      </Button>
    );
  };

  const SettingsToggle = () => {
    if (!styleState.isMobile) return null;
    return (
      <Button
        icon={<Settings size={16} />}
        style={{
          position: 'absolute',
          left: showSettings ? -10 : -20,
          top: '50%',
          transform: 'translateY(-50%)',
          zIndex: 1000,
          width: 40,
          height: 40,
          borderRadius: '0 20px 20px 0',
          padding: 0,
          boxShadow: '2px 0 8px rgba(0, 0, 0, 0.15)',
        }}
        onClick={() => setShowSettings(!showSettings)}
        theme='solid'
        type='primary'
      />
    );
  };

  function CustomInputRender(props) {
    const { detailProps } = props;
    const { clearContextNode, uploadNode, inputNode, sendNode, onClick } =
      detailProps;

    return (
      <div className="p-4">
        <div
          className="flex items-end gap-3 p-4 bg-gray-50 rounded-2xl shadow-sm hover:shadow-md transition-shadow"
          style={{ border: '1px solid var(--semi-color-border)' }}
          onClick={onClick}
        >
          <div className="flex-1">
            {inputNode}
          </div>
          <Button
            theme="solid"
            type="primary"
            className="!rounded-lg !bg-purple-500 hover:!bg-purple-600 flex-shrink-0"
            icon={<IconSend />}
          >
            {t('发送')}
          </Button>
        </div>
      </div>
    );
  }

  const renderInputArea = useCallback((props) => {
    return <CustomInputRender {...props} />;
  }, []);

  const renderChatBoxAction = useCallback((props) => {
    const { message } = props;

    const isLoading = message.status === 'loading' || message.status === 'incomplete';

    return (
      <div className="flex items-center gap-0.5">
        {!isLoading && (
          <Tooltip content={t('重试')} position="top">
            <Button
              theme="borderless"
              type="tertiary"
              size="small"
              icon={<RefreshCw size={14} />}
              onClick={() => handleMessageReset(message)}
              className="!rounded-md !text-gray-400 hover:!text-blue-600 hover:!bg-blue-50 !w-7 !h-7 !p-0 transition-all"
              aria-label={t('重试')}
            />
          </Tooltip>
        )}

        {message.content && (
          <Tooltip content={t('复制')} position="top">
            <Button
              theme="borderless"
              type="tertiary"
              size="small"
              icon={<Copy size={14} />}
              onClick={() => handleMessageCopy(message)}
              className="!rounded-md !text-gray-400 hover:!text-green-600 hover:!bg-green-50 !w-7 !h-7 !p-0 transition-all"
              aria-label={t('复制')}
            />
          </Tooltip>
        )}

        {!isLoading && (
          <Tooltip content={t('删除')} position="top">
            <Button
              theme="borderless"
              type="tertiary"
              size="small"
              icon={<Trash2 size={14} />}
              onClick={() => handleMessageDelete(message)}
              className="!rounded-md !text-gray-400 hover:!text-red-600 hover:!bg-red-50 !w-7 !h-7 !p-0 transition-all"
              aria-label={t('删除')}
            />
          </Tooltip>
        )}
      </div>
    );
  }, [handleMessageReset, handleMessageCopy, handleMessageDelete, t]);

  const renderCustomChatContent = useCallback(
    ({ message, className }) => {
      if (message.status === 'error') {
        return (
          <div className={`${className} flex items-center p-4 bg-red-50 rounded-xl`}>
            <Typography.Text type="danger" className="text-sm">
              {message.content || t('请求发生错误')}
            </Typography.Text>
          </div>
        );
      }

      const toggleReasoningExpansion = (messageId) => {
        setMessage(prevMessages =>
          prevMessages.map(msg =>
            msg.id === messageId && msg.role === 'assistant'
              ? { ...msg, isReasoningExpanded: !msg.isReasoningExpanded }
              : msg
          )
        );
      };

      const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
      let currentExtractedThinkingContent = null;
      let currentDisplayableFinalContent = message.content || "";

      if (message.role === 'assistant') {
        if (message.reasoningContent) {
          currentExtractedThinkingContent = message.reasoningContent;
        }

        currentDisplayableFinalContent = message.content || "";
      }

      const headerText = isThinkingStatus ? t('思考中...') : t('思考过程');
      const finalExtractedThinkingContent = currentExtractedThinkingContent;
      const finalDisplayableFinalContent = currentDisplayableFinalContent;

      if (message.role === 'assistant' &&
        isThinkingStatus &&
        !finalExtractedThinkingContent &&
        (!finalDisplayableFinalContent || finalDisplayableFinalContent.trim() === '')) {
        return (
          <div className={`${className} flex items-center gap-4 p-6 bg-gradient-to-r from-purple-50 to-indigo-50 rounded-2xl`}>
            <div className="w-10 h-10 rounded-full bg-gradient-to-br from-purple-500 to-indigo-600 flex items-center justify-center shadow-lg">
              <Loader2 className="animate-spin text-white" size={20} />
            </div>
            <div className="flex flex-col">
              <Typography.Text strong className="text-gray-800 text-base">
                {t('正在思考...')}
              </Typography.Text>
              <Typography.Text className="text-gray-500 text-sm">
                AI 正在分析您的问题
              </Typography.Text>
            </div>
          </div>
        );
      }

      return (
        <div className={className}>
          {message.role === 'assistant' && finalExtractedThinkingContent && (
            <div className="bg-gradient-to-br from-indigo-50 via-purple-50 to-pink-50 rounded-2xl mb-4 overflow-hidden shadow-sm backdrop-blur-sm">
              <div
                className="flex items-center justify-between p-5 cursor-pointer hover:bg-gradient-to-r hover:from-white/40 hover:to-purple-50/60 transition-all"
                onClick={() => toggleReasoningExpansion(message.id)}
              >
                <div className="flex items-center gap-4">
                  <div className="w-8 h-8 rounded-full bg-gradient-to-br from-purple-500 to-indigo-600 flex items-center justify-center shadow-lg">
                    <Brain className="text-white" size={16} />
                  </div>
                  <div className="flex flex-col">
                    <Typography.Text strong className="text-gray-800 text-base">
                      {headerText}
                    </Typography.Text>
                    <Typography.Text className="text-gray-500 text-xs mt-0.5">
                      来源: reasoning_content
                    </Typography.Text>
                  </div>
                </div>
                <div className="flex items-center gap-3">
                  {isThinkingStatus && (
                    <div className="flex items-center gap-2">
                      <Loader2 className="animate-spin text-purple-500" size={18} />
                      <Typography.Text className="text-purple-600 text-sm font-medium">
                        思考中
                      </Typography.Text>
                    </div>
                  )}
                  {!isThinkingStatus && (
                    <div className="w-6 h-6 rounded-full bg-purple-100 flex items-center justify-center">
                      {message.isReasoningExpanded ?
                        <ChevronUp size={16} className="text-purple-600" /> :
                        <ChevronRight size={16} className="text-purple-600" />
                      }
                    </div>
                  )}
                </div>
              </div>
              <div
                className={`transition-all duration-500 ease-out ${message.isReasoningExpanded ? 'max-h-96 opacity-100' : 'max-h-0 opacity-0'
                  } overflow-hidden`}
              >
                {message.isReasoningExpanded && (
                  <div className="p-5 pt-4">
                    <div className="bg-white/70 backdrop-blur-sm rounded-xl p-4 shadow-inner overflow-x-auto max-h-50 overflow-y-auto">
                      <div className="prose prose-sm prose-purple max-w-none">
                        <Typography.Paragraph className="whitespace-pre-wrap">
                          {finalExtractedThinkingContent}
                        </Typography.Paragraph>
                      </div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          )}

          {(finalDisplayableFinalContent && finalDisplayableFinalContent.trim() !== '') && (
            <div className="prose prose-sm prose-gray max-w-none overflow-x-auto">
              <Typography.Paragraph className="whitespace-pre-wrap">
                {finalDisplayableFinalContent}
              </Typography.Paragraph>
            </div>
          )}
        </div>
      );
    },
    [t, setMessage],
  );

  return (
    <div className="min-h-screen bg-gray-50">
      <Layout style={{ height: '100vh', background: 'transparent' }}>
        {(showSettings || !styleState.isMobile) && (
          <Layout.Sider
            style={{
              background: 'transparent',
              borderRight: 'none',
              flexShrink: 0,
              minWidth: 320,
              maxWidth: 320,
              height: 'calc(100vh - 100px)',
            }}
            width={320}
          >
            <Card className="!rounded-2xl h-full flex flex-col" bodyStyle={{ padding: '24px', height: '100%', display: 'flex', flexDirection: 'column' }}>
              <div className="flex items-center justify-between mb-6 flex-shrink-0">
                <div className="flex items-center">
                  <div className="w-10 h-10 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center mr-3">
                    <SlidersHorizontal size={20} className="text-white" />
                  </div>
                  <Typography.Title heading={5} className="mb-0">
                    {t('模型设置')}
                  </Typography.Title>
                </div>
                <DebugToggle />
              </div>

              <div className="space-y-6 overflow-y-auto flex-1 pr-2 model-settings-scroll">
                {/* 分组选择 */}
                <div>
                  <div className="flex items-center gap-2 mb-2">
                    <Users size={16} className="text-gray-500" />
                    <Typography.Text strong className="text-sm">
                      {t('分组')}
                    </Typography.Text>
                  </div>
                  <Select
                    placeholder={t('请选择分组')}
                    name='group'
                    required
                    selection
                    onChange={(value) => handleInputChange('group', value)}
                    value={inputs.group}
                    autoComplete='new-password'
                    optionList={groups}
                    renderOptionItem={renderGroupOption}
                    style={{ width: '100%' }}
                    className="!rounded-lg"
                  />
                </div>

                {/* 模型选择 */}
                <div>
                  <div className="flex items-center gap-2 mb-2">
                    <Sparkles size={16} className="text-gray-500" />
                    <Typography.Text strong className="text-sm">
                      {t('模型')}
                    </Typography.Text>
                  </div>
                  <Select
                    placeholder={t('请选择模型')}
                    name='model'
                    required
                    selection
                    searchPosition='dropdown'
                    filter
                    onChange={(value) => handleInputChange('model', value)}
                    value={inputs.model}
                    autoComplete='new-password'
                    optionList={models}
                    className="!rounded-lg"
                  />
                </div>

                {/* Temperature */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.temperature ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Thermometer size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Temperature
                      </Typography.Text>
                      <Tag size="small" className="!rounded-full">
                        {inputs.temperature}
                      </Tag>
                    </div>
                    <Button
                      theme={parameterEnabled.temperature ? 'solid' : 'borderless'}
                      type={parameterEnabled.temperature ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.temperature ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('temperature')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Typography.Text className="text-xs text-gray-500 mb-2">
                    控制输出的随机性和创造性
                  </Typography.Text>
                  <Slider
                    step={0.1}
                    min={0.1}
                    max={1}
                    value={inputs.temperature}
                    onChange={(value) => handleInputChange('temperature', value)}
                    className="mt-2"
                    disabled={!parameterEnabled.temperature}
                  />
                </div>

                {/* Top P */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.top_p ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Target size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Top P
                      </Typography.Text>
                      <Tag size="small" className="!rounded-full">
                        {inputs.top_p}
                      </Tag>
                    </div>
                    <Button
                      theme={parameterEnabled.top_p ? 'solid' : 'borderless'}
                      type={parameterEnabled.top_p ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.top_p ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('top_p')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Typography.Text className="text-xs text-gray-500 mb-2">
                    核采样，控制词汇选择的多样性
                  </Typography.Text>
                  <Slider
                    step={0.1}
                    min={0.1}
                    max={1}
                    value={inputs.top_p}
                    onChange={(value) => handleInputChange('top_p', value)}
                    className="mt-2"
                    disabled={!parameterEnabled.top_p}
                  />
                </div>

                {/* Frequency Penalty */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.frequency_penalty ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Repeat size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Frequency Penalty
                      </Typography.Text>
                      <Tag size="small" className="!rounded-full">
                        {inputs.frequency_penalty}
                      </Tag>
                    </div>
                    <Button
                      theme={parameterEnabled.frequency_penalty ? 'solid' : 'borderless'}
                      type={parameterEnabled.frequency_penalty ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.frequency_penalty ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('frequency_penalty')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Typography.Text className="text-xs text-gray-500 mb-2">
                    频率惩罚，减少重复词汇的出现
                  </Typography.Text>
                  <Slider
                    step={0.1}
                    min={-2}
                    max={2}
                    value={inputs.frequency_penalty}
                    onChange={(value) => handleInputChange('frequency_penalty', value)}
                    className="mt-2"
                    disabled={!parameterEnabled.frequency_penalty}
                  />
                </div>

                {/* Presence Penalty */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.presence_penalty ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Ban size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Presence Penalty
                      </Typography.Text>
                      <Tag size="small" className="!rounded-full">
                        {inputs.presence_penalty}
                      </Tag>
                    </div>
                    <Button
                      theme={parameterEnabled.presence_penalty ? 'solid' : 'borderless'}
                      type={parameterEnabled.presence_penalty ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.presence_penalty ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('presence_penalty')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Typography.Text className="text-xs text-gray-500 mb-2">
                    存在惩罚，鼓励讨论新话题
                  </Typography.Text>
                  <Slider
                    step={0.1}
                    min={-2}
                    max={2}
                    value={inputs.presence_penalty}
                    onChange={(value) => handleInputChange('presence_penalty', value)}
                    className="mt-2"
                    disabled={!parameterEnabled.presence_penalty}
                  />
                </div>

                {/* MaxTokens */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.max_tokens ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Hash size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Max Tokens
                      </Typography.Text>
                    </div>
                    <Button
                      theme={parameterEnabled.max_tokens ? 'solid' : 'borderless'}
                      type={parameterEnabled.max_tokens ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.max_tokens ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('max_tokens')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Input
                    placeholder='MaxTokens'
                    name='max_tokens'
                    required
                    autoComplete='new-password'
                    defaultValue={0}
                    value={inputs.max_tokens}
                    onChange={(value) => handleInputChange('max_tokens', value)}
                    className="!rounded-lg"
                    disabled={!parameterEnabled.max_tokens}
                  />
                </div>

                {/* Seed */}
                <div className={`transition-opacity duration-200 ${!parameterEnabled.seed ? 'opacity-50' : ''}`}>
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <Shuffle size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        Seed
                      </Typography.Text>
                      <Typography.Text className="text-xs text-gray-400">
                        (可选，用于复现结果)
                      </Typography.Text>
                    </div>
                    <Button
                      theme={parameterEnabled.seed ? 'solid' : 'borderless'}
                      type={parameterEnabled.seed ? 'primary' : 'tertiary'}
                      size="small"
                      icon={parameterEnabled.seed ? <Check size={10} /> : <X size={10} />}
                      onClick={() => handleParameterToggle('seed')}
                      className="!rounded-full !w-6 !h-6 !p-0 !min-w-0"
                    />
                  </div>
                  <Input
                    placeholder='随机种子 (留空为随机)'
                    name='seed'
                    autoComplete='new-password'
                    value={inputs.seed || ''}
                    onChange={(value) => handleInputChange('seed', value === '' ? null : value)}
                    className="!rounded-lg"
                    disabled={!parameterEnabled.seed}
                  />
                </div>

                {/* Stream Toggle */}
                <div>
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <ToggleLeft size={16} className="text-gray-500" />
                      <Typography.Text strong className="text-sm">
                        流式输出
                      </Typography.Text>
                    </div>
                    <Button
                      theme={inputs.stream ? 'solid' : 'borderless'}
                      type={inputs.stream ? 'primary' : 'tertiary'}
                      size="small"
                      onClick={() => handleInputChange('stream', !inputs.stream)}
                      className="!rounded-full"
                    >
                      {inputs.stream ? '开启' : '关闭'}
                    </Button>
                  </div>
                </div>

                {/* System Prompt */}
                <div>
                  <div className="flex items-center gap-2 mb-2">
                    <Type size={16} className="text-gray-500" />
                    <Typography.Text strong className="text-sm">
                      System Prompt
                    </Typography.Text>
                  </div>
                  <TextArea
                    placeholder='System Prompt'
                    name='system'
                    required
                    autoComplete='new-password'
                    autosize
                    defaultValue={systemPrompt}
                    onChange={(value) => setSystemPrompt(value)}
                    className="!rounded-lg"
                    maxHeight={200}
                  />
                </div>
              </div>
            </Card>
          </Layout.Sider>
        )}

        <Layout.Content className="relative flex-1 overflow-hidden">
          <div className="px-4 overflow-hidden flex gap-4" style={{ height: 'calc(100vh - 100px)' }}>
            <div className="flex-1 flex flex-col">
              <SettingsToggle />
              <Card
                className="!rounded-2xl h-full"
                bodyStyle={{ padding: 0, height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
              >
                {/* 聊天头部 */}
                <div className="px-6 py-4 bg-gradient-to-r from-purple-500 to-blue-500 rounded-t-2xl">
                  <div className="flex items-center gap-3">
                    <div className="w-10 h-10 rounded-full bg-white/20 backdrop-blur flex items-center justify-center">
                      <MessageSquare size={20} className="text-white" />
                    </div>
                    <div>
                      <Typography.Title heading={5} className="!text-white mb-0">
                        {t('AI 对话')}
                      </Typography.Title>
                      <Typography.Text className="!text-white/80 text-sm">
                        {inputs.model || t('选择模型开始对话')}
                      </Typography.Text>
                    </div>
                  </div>
                </div>

                {/* 聊天内容区域 */}
                <div className="flex-1 overflow-hidden">
                  <Chat
                    chatBoxRenderConfig={{
                      renderChatBoxContent: renderCustomChatContent,
                      renderChatBoxAction: renderChatBoxAction,
                    }}
                    renderInputArea={renderInputArea}
                    roleConfig={roleInfo}
                    style={{
                      height: '100%',
                      maxWidth: '100%',
                      overflow: 'hidden'
                    }}
                    chats={message}
                    onMessageSend={onMessageSend}
                    onMessageCopy={handleMessageCopy}
                    onMessageReset={handleMessageReset}
                    onMessageDelete={handleMessageDelete}
                    showClearContext
                    showStopGenerate
                    onStopGenerator={onStopGenerator}
                    onClear={() => setMessage([])}
                    className="h-full"
                    placeholder={t('请输入您的问题...')}
                  />
                </div>
              </Card>
            </div>

            {/* 调试面板 */}
            {showDebugPanel && (
              <div className="w-96 flex-shrink-0">
                <Card className="!rounded-2xl h-full flex flex-col" bodyStyle={{ padding: '24px', height: '100%', display: 'flex', flexDirection: 'column' }}>
                  <div className="flex items-center mb-6 flex-shrink-0">
                    <div className="w-10 h-10 rounded-full bg-gradient-to-r from-green-500 to-blue-500 flex items-center justify-center mr-3">
                      <Code size={20} className="text-white" />
                    </div>
                    <Typography.Title heading={5} className="mb-0">
                      {t('调试信息')}
                    </Typography.Title>
                  </div>

                  <div className="flex-1 overflow-hidden debug-panel">
                    <Tabs
                      type="line"
                      className="h-full"
                      style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
                      activeKey={activeDebugTab}
                      onChange={setActiveDebugTab}
                    >
                      <TabPane tab={
                        <div className="flex items-center gap-2">
                          <FileText size={16} />
                          {t('请求体')}
                        </div>
                      } itemKey="request">
                        <div className="h-full overflow-y-auto bg-gray-50 rounded-lg p-4 model-settings-scroll">
                          {debugData.request ? (
                            <pre className="debug-code text-gray-700 whitespace-pre-wrap break-words">
                              {JSON.stringify(debugData.request, null, 2)}
                            </pre>
                          ) : (
                            <Typography.Text type="secondary" className="text-sm">
                              {t('暂无请求数据')}
                            </Typography.Text>
                          )}
                        </div>
                      </TabPane>

                      <TabPane tab={
                        <div className="flex items-center gap-2">
                          <Zap size={16} />
                          {t('响应内容')}
                        </div>
                      } itemKey="response">
                        <div className="h-full overflow-y-auto bg-gray-50 rounded-lg p-4 model-settings-scroll">
                          {debugData.response ? (
                            <pre className="debug-code text-gray-700 whitespace-pre-wrap break-words">
                              {debugData.response}
                            </pre>
                          ) : (
                            <Typography.Text type="secondary" className="text-sm">
                              {t('暂无响应数据')}
                            </Typography.Text>
                          )}
                        </div>
                      </TabPane>
                    </Tabs>
                  </div>

                  {debugData.timestamp && (
                    <div className="flex items-center gap-2 mt-4 pt-4 flex-shrink-0">
                      <Clock size={14} className="text-gray-500" />
                      <Typography.Text className="text-xs text-gray-500">
                        {t('最后更新')}: {new Date(debugData.timestamp).toLocaleString()}
                      </Typography.Text>
                    </div>
                  )}
                </Card>
              </div>
            )}
          </div>
        </Layout.Content>
      </Layout>
    </div>
  );
};

export default Playground;
