import React, { useEffect } from 'react';
import './style.less';
import ReactMarkdown from 'react-markdown';
import { createFromIconfontCN, LoadingOutlined } from '@ant-design/icons';
import { Spin, Tooltip } from 'antd';
import { Column, Line, Pie } from '@ant-design/charts';

export interface Message {
  id?: string; // 创建消息时赋予唯一 id
  sender: 'user' | 'bot';
  thinkContent?: string;
  content: string; // 可能包含纯文本或 HTML
  loading?: boolean;
  duration?: number; // 回答耗时（秒）
  collapse?: boolean; // 保存折叠状态
  complete?: boolean;
  contentType?: string;
  charts?: {
    type: 'LineChart' | 'ColumnChart' | 'PieChart';
    xField: string;
    yField: string;
    angleField: string;
    colorField: string;
    data: any[];
  };
}

const IconFont = createFromIconfontCN({
  scriptUrl: '', // 请填写图标脚本地址
});

const antIcon = <LoadingOutlined style={{ fontSize: 14, color: '#17181A' }} spin />;

// 单独封装一个 memoized 的 Spinner 组件，避免频繁重绘导致动画重置
const SpinnerComponent: React.FC<{ loading: boolean }> = React.memo(({ loading }) => {
  return loading ? <Spin indicator={antIcon} style={{ paddingRight: 8 }} /> : null;
});

// 拆分机器人消息中的状态部分（头像旁边那块）
// 新增属性 hasDeepThinking，根据该属性显示不同的文案
interface BotMessageStatusProps {
  loading: boolean;
  duration?: number;
  collapse: boolean;
  onToggleCollapse: () => void;
  hasDeepThinking: boolean;
}
const BotMessageStatus: React.FC<BotMessageStatusProps> = React.memo(
  ({ loading, duration, collapse, onToggleCollapse, hasDeepThinking }) => {
    return (
      <div className="bot-message-status">
        {loading ? (
          <>
            <SpinnerComponent loading={loading} />
            {hasDeepThinking ? '深度思考中…' : '内容输出中…'}
          </>
        ) : (
          <>
            {hasDeepThinking ? `已深度思考${duration ? `(用时${duration}秒)` : ''}` : `内容已输出完毕${duration ? `(用时${duration}秒)` : ''}`}
            {hasDeepThinking && <IconFont type={collapse ? 'iconxiangxia' : 'iconxiangshang'} onClick={onToggleCollapse} style={{ cursor: 'pointer', paddingLeft: 8, fontSize: 16 }} />}
          </>
        )}
      </div>
    );
  },
  (prevProps, nextProps) =>
    prevProps.loading === nextProps.loading && prevProps.duration === nextProps.duration && prevProps.collapse === nextProps.collapse && prevProps.hasDeepThinking === nextProps.hasDeepThinking,
);

// 拆分机器人消息中的文本内容部分，同时处理图表展示
interface BotMessageContentProps {
  thinkContent?: string;
  content: string;
  msg: Message;
  charts?: {
    type: string;
    xField: string;
    yField: string;
    angleField: string;
    colorField: string;
    data: any[];
  };
  // 新增 onShowDetail 回调属性，用于点击详情按钮时触发
  onShowDetail?: (charts: any, content: string) => void;
}

const BotMessageContent: React.FC<BotMessageContentProps> = React.memo(({ thinkContent, content, charts, onShowDetail, msg }) => {
 
  return (
    <div className="bot-message-text">
      <div className="think-text">{thinkContent}</div>
      <div className="msg-content">
        {/* 判断是否存在图表数据 */}
        {charts && charts.data && charts.data.length > 0 && (
          <div className={msg.content.length > 0 && msg.complete ? 'charts-content canReadDetail' : 'charts-content'}>
            <div className="charts-detail-btn" onClick={() => onShowDetail && onShowDetail(charts, content)}>
              <IconFont type={'iconchakan'} style={{ fontSize: 16, paddingRight: 4 }} />
              详情
            </div>
            {(charts.type === 'LineChart' && charts) && <Line {...charts} />}
            {charts.type === 'ColumnChart' && <Column {...charts} />}
            {charts.type === 'PieChart' && <Pie {...charts} />}
          </div>
        )}
        <ReactMarkdown skipHtml={false}>{content}</ReactMarkdown>
      </div>
    </div>
  );
});

// 整体的机器人消息组件
interface BotMessageProps {
  msg: Message;
  onToggleCollapse: () => void;
  handleCopy: (text: string) => void;
  ifCopied: boolean;
  // 新增 onShowDetail 回调属性
  onShowDetail?: (charts: any, content: string) => void;
}
const BotMessage: React.FC<BotMessageProps> = ({ msg, onToggleCollapse, handleCopy, ifCopied, onShowDetail }) => {
  const isCollapsed = msg.collapse || false;
  // 通过判断 thinkContent 是否存在且非空来确定是否存在深度思考内容
  const hasDeepThinking = !!(msg.thinkContent && msg.thinkContent.trim().length > 0);
  return (
    <div className="bot-message-content">
      <div className="bot-message-avatar">
        <img src={require('../images/ai-avator.png')} alt="" />
        <BotMessageStatus loading={msg.loading || false} duration={msg.duration} collapse={isCollapsed} onToggleCollapse={onToggleCollapse} hasDeepThinking={hasDeepThinking} />
      </div>
      <BotMessageContent
        thinkContent={isCollapsed ? '' : msg.thinkContent}
        content={msg.content}
        msg={msg}
        charts={msg.charts} // 传递图表数据
        onShowDetail={onShowDetail}
      />
      {msg.content.length > 0 && msg.complete && (
        <Tooltip title={ifCopied ? '已复制' : '点击复制'}>
          <div className="copyBtn" onClick={() => handleCopy(msg.content)}>
            <IconFont type={'iconfuzhi'} style={{ cursor: 'pointer', fontSize: 16 }} />
          </div>
        </Tooltip>
      )}
    </div>
  );
};

interface ChatProps {
  messages: Message[];
  chatContainerRef: React.RefObject<HTMLDivElement>;
  setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
  // 新增 onShowDetail 回调属性，用于将详情数据传递到上层组件（例如 AiChat）
  onShowDetail?: (charts: any, content: string) => void;
}

const Chat: React.FC<ChatProps> = ({ messages, chatContainerRef, setMessages, onShowDetail }) => {
  const [ifCopied, setIfCopied] = React.useState<boolean>(false);

  const fallbackCopyTextToClipboard = (text: string) => {
    const textArea = document.createElement('textarea');
    textArea.value = text;
    textArea.style.position = 'fixed';
    textArea.style.top = '0';
    textArea.style.left = '0';
    textArea.style.width = '2em';
    textArea.style.height = '2em';
    textArea.style.padding = '0';
    textArea.style.border = 'none';
    textArea.style.outline = 'none';
    textArea.style.boxShadow = 'none';
    textArea.style.background = 'transparent';
    document.body.appendChild(textArea);
    textArea.select();
    try { 
      const successful = document.execCommand('copy');
      if (successful) setIfCopied(true);
    } catch (err) {
      console.error('复制失败', err);
    }
    document.body.removeChild(textArea);
  };

  const handleCopy = (text: string) => {
    if (!text) {
      console.error('未获取到文本内容');
      return;
    }
    if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
      navigator.clipboard
        .writeText(text)
        .then(() => {
          setIfCopied(true);
        })
        .catch((err) => {
          console.error('使用 Clipboard API 复制失败，尝试备用方案：', err);
          fallbackCopyTextToClipboard(text);
        });
    } else {
      fallbackCopyTextToClipboard(text);
    }
  };

  useEffect(() => {
    if (ifCopied) {
      const timer = setTimeout(() => {
        setIfCopied(false);
      }, 2000);
      return () => clearTimeout(timer);
    }
  }, [ifCopied]);

  return (
    <div className="chat-container" ref={chatContainerRef}>
      {messages.map((msg, idx) => {
        const key = msg.id || idx;
        if (msg.sender === 'user') {
          return (
            <div key={key} className="chat-message user-message">
              <div>{msg.content}</div>
            </div>
          );
        } else {
          return (
            <div key={key} className="chat-message bot-message">
              <BotMessage
                msg={msg}
                onToggleCollapse={() => {
                  setMessages((prevMessages) => prevMessages.map((m, i) => (i === idx ? { ...m, collapse: !m.collapse } : m)));
                }}
                handleCopy={handleCopy}
                ifCopied={ifCopied}
                onShowDetail={onShowDetail}
              />
            </div>
          );
        }
      })}
    </div>
  );
};

export default Chat;
