import HightLightMarkdown from '@/components/highlight-markdown';
import { useTranslate } from '@/hooks/common-hooks';
// 假设 aiAssistantConfig 在实际项目中是正确导入的
// import { aiAssistantConfig } from '@/pages/write/ai-assistant-config';
const aiAssistantConfig = { api: { timeout: 30000 } }; // 模拟定义

import { DeleteOutlined } from '@ant-design/icons';
import {
  Button,
  Card,
  Divider,
  Flex,
  Form,
  Input,
  Layout,
  List,
  message,
  Modal,
  Popconfirm,
  Select,
  Slider,
  Space,
  Typography,
} from 'antd';
import axios from 'axios';
import {
  AlignmentType,
  Document,
  HeadingLevel,
  Packer,
  Paragraph,
  TextRun,
} from 'docx';
import { saveAs } from 'file-saver';
import { marked, Token, Tokens } from 'marked'; // 从 marked 导入 Token 和 Tokens 类型
import { useCallback, useEffect, useRef, useState } from 'react';

const { Sider, Content } = Layout;
const { Option } = Select;

const LOCAL_STORAGE_TEMPLATES_KEY = 'userWriteTemplates_v4_no_restore_final';
const LOCAL_STORAGE_INIT_FLAG_KEY =
  'userWriteTemplates_initialized_v4_no_restore_final';

interface TemplateItem {
  id: string;
  name: string;
  content: string;
  isCustom?: boolean;
}
interface KnowledgeBaseItem {
  id: string;
  name: string;
}

// 使用 marked 导出的类型或更精确的自定义类型
type MarkedHeadingToken = Tokens.Heading;
type MarkedParagraphToken = Tokens.Paragraph;
type MarkedListItem = Tokens.ListItem;
type MarkedListToken = Tokens.List;
type MarkedSpaceToken = Tokens.Space;

const Write = () => {
  const { t } = useTranslate('write');
  const [content, setContent] = useState('');
  const [aiQuestion, setAiQuestion] = useState('');
  const [isAiLoading, setIsAiLoading] = useState(false);
  const [dialogId, setDialogId] = useState('');
  const [cursorPosition, setCursorPosition] = useState<number | null>(null);
  const [showCursorIndicator, setShowCursorIndicator] = useState(false);
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const [templates, setTemplates] = useState<TemplateItem[]>([]);
  const [isTemplateModalVisible, setIsTemplateModalVisible] = useState(false);
  const [templateName, setTemplateName] = useState('');
  const [selectedTemplate, setSelectedTemplate] = useState<string>('');
  const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'split'>(
    'split',
  );

  const [selectedKnowledgeBases, setSelectedKnowledgeBases] = useState<
    string[]
  >([]);
  const [similarityThreshold, setSimilarityThreshold] = useState<number>(0.7);
  const [keywordSimilarityWeight, setKeywordSimilarityWeight] =
    useState<number>(0.5);
  const [modelTemperature, setModelTemperature] = useState<number>(0.7);
  const [knowledgeBases, setKnowledgeBases] = useState<KnowledgeBaseItem[]>([]);
  const [isLoadingKbs, setIsLoadingKbs] = useState(false);

  const getInitialDefaultTemplateDefinitions = useCallback(
    (): TemplateItem[] => [
      {
        id: 'default_1_v4f',
        name: t('defaultTemplate'),
        content: `# ${t('defaultTemplateTitle')}\n ## ${t('introduction')}\n  ## ${t('mainContent')}\n  \n  ## ${t('conclusion')}\n  `,
        isCustom: false,
      },
      {
        id: 'default_2_v4f',
        name: t('technicalDoc'),
        content: `# ${t('technicalDocTitle')}\n  \n  ## ${t('overview')}\n  \n  ## ${t('requirements')}\n  \n  ## ${t('architecture')}\n  \n  ## ${t('implementation')}\n  \n  ## ${t('testing')}\n  \n  ## ${t('deployment')}\n  \n  ## ${t('maintenance')}\n  `,
        isCustom: false,
      },
      {
        id: 'default_3_v4f',
        name: t('meetingMinutes'),
        content: `# ${t('meetingMinutesTitle')}\n  \n  ## ${t('date')}: ${new Date().toLocaleDateString()}\n  \n  ## ${t('participants')}\n  \n  ## ${t('agenda')}\n  \n  ## ${t('discussions')}\n  \n  ## ${t('decisions')}\n  \n  ## ${t('actionItems')}\n  \n  ## ${t('nextMeeting')}\n  `,
        isCustom: false,
      },
    ],
    [t],
  );

  const loadOrInitializeTemplates = useCallback(() => {
    try {
      const initialized = localStorage.getItem(LOCAL_STORAGE_INIT_FLAG_KEY);
      let currentTemplates: TemplateItem[] = [];
      if (initialized === 'true') {
        const savedTemplatesString = localStorage.getItem(
          LOCAL_STORAGE_TEMPLATES_KEY,
        );
        currentTemplates = savedTemplatesString
          ? JSON.parse(savedTemplatesString)
          : getInitialDefaultTemplateDefinitions();
        if (!savedTemplatesString) {
          localStorage.setItem(
            LOCAL_STORAGE_TEMPLATES_KEY,
            JSON.stringify(currentTemplates),
          );
        }
      } else {
        currentTemplates = getInitialDefaultTemplateDefinitions();
        localStorage.setItem(
          LOCAL_STORAGE_TEMPLATES_KEY,
          JSON.stringify(currentTemplates),
        );
        localStorage.setItem(LOCAL_STORAGE_INIT_FLAG_KEY, 'true');
      }
      setTemplates(currentTemplates);
      if (currentTemplates.length > 0 && !selectedTemplate) {
        setSelectedTemplate(currentTemplates[0].id);
        setContent(currentTemplates[0].content);
      } else if (selectedTemplate) {
        const current = currentTemplates.find(
          (ts) => ts.id === selectedTemplate,
        );
        if (current) setContent(current.content);
        else if (currentTemplates.length > 0) {
          setSelectedTemplate(currentTemplates[0].id);
          setContent(currentTemplates[0].content);
        } else {
          setSelectedTemplate('');
          setContent('');
        }
      }
    } catch (error) {
      console.error('加载或初始化模板失败:', error);
      message.error(t('loadTemplatesFailedError'));
      const fallbackDefaults = getInitialDefaultTemplateDefinitions();
      setTemplates(fallbackDefaults);
      if (fallbackDefaults.length > 0) {
        setSelectedTemplate(fallbackDefaults[0].id);
        setContent(fallbackDefaults[0].content);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [t, getInitialDefaultTemplateDefinitions]);

  useEffect(() => {
    loadOrInitializeTemplates();
  }, [loadOrInitializeTemplates]);

  useEffect(() => {
    const fetchKbs = async () => {
      const authorization = localStorage.getItem('Authorization');
      if (!authorization) {
        setKnowledgeBases([]);
        return;
      }
      setIsLoadingKbs(true);
      try {
        await new Promise((resolve) => {
          setTimeout(resolve, 500);
        });
        const mockKbs: KnowledgeBaseItem[] = [
          {
            id: 'kb_default',
            name: t('defaultKnowledgeBase', { defaultValue: '默认知识库' }),
          },
          {
            id: 'kb_tech',
            name: t('technicalDocsKnowledgeBase', {
              defaultValue: '技术文档知识库',
            }),
          },
          {
            id: 'kb_product',
            name: t('productInfoKnowledgeBase', {
              defaultValue: '产品信息知识库',
            }),
          },
          {
            id: 'kb_marketing',
            name: t('marketingMaterialsKB', { defaultValue: '市场营销材料库' }),
          },
          {
            id: 'kb_legal',
            name: t('legalDocumentsKB', { defaultValue: '法律文件库' }),
          },
        ];
        setKnowledgeBases(mockKbs);
      } catch (error) {
        console.error('获取知识库失败:', error);
        message.error(t('fetchKnowledgeBaseFailed'));
        setKnowledgeBases([]);
      } finally {
        setIsLoadingKbs(false);
      }
    };
    fetchKbs();
  }, [t]);

  useEffect(() => {
    const fetchDialogs = async () => {
      try {
        const authorization = localStorage.getItem('Authorization');
        if (!authorization) return;
        const response = await axios.get('/v1/dialog', {
          headers: { authorization },
        });
        if (response.data?.data?.length > 0)
          setDialogId(response.data.data[0].id);
      } catch (error) {
        console.error('获取对话列表失败:', error);
      }
    };
    const loadDraftContent = () => {
      try {
        const draftContent = localStorage.getItem('writeDraftContent');
        if (
          draftContent &&
          !content &&
          (!selectedTemplate ||
            templates.find((t) => t.id === selectedTemplate)?.content === '')
        ) {
          setContent(draftContent);
        }
      } catch (error) {
        console.error('加载暂存内容失败:', error);
      }
    };
    fetchDialogs();
    if (localStorage.getItem(LOCAL_STORAGE_INIT_FLAG_KEY) === 'true') {
      loadDraftContent();
    }
  }, [content, selectedTemplate, templates]);

  useEffect(() => {
    const timer = setTimeout(
      () => localStorage.setItem('writeDraftContent', content),
      1000,
    );
    return () => clearTimeout(timer);
  }, [content]);

  const handleTemplateSelect = (templateId: string) => {
    setSelectedTemplate(templateId);
    const item = templates.find((t) => t.id === templateId);
    if (item) setContent(item.content);
  };

  const handleSaveTemplate = () => {
    if (!templateName.trim()) {
      message.warning(t('enterTemplateName'));
      return;
    }
    if (!content.trim()) {
      message.warning(t('enterTemplateContent'));
      return;
    }
    const newTemplate: TemplateItem = {
      id: `custom_${Date.now()}`,
      name: templateName,
      content,
      isCustom: true,
    };
    try {
      const updatedTemplates = [...templates, newTemplate];
      setTemplates(updatedTemplates);
      localStorage.setItem(
        LOCAL_STORAGE_TEMPLATES_KEY,
        JSON.stringify(updatedTemplates),
      );
      message.success(t('templateSavedSuccess'));
      setIsTemplateModalVisible(false);
      setTemplateName('');
      setSelectedTemplate(newTemplate.id);
    } catch (error) {
      console.error('保存模板失败:', error);
      message.error(t('templateSavedFailed'));
    }
  };

  const handleDeleteTemplate = (templateId: string) => {
    try {
      const updatedTemplates = templates.filter((t) => t.id !== templateId);
      setTemplates(updatedTemplates);
      localStorage.setItem(
        LOCAL_STORAGE_TEMPLATES_KEY,
        JSON.stringify(updatedTemplates),
      );
      if (selectedTemplate === templateId) {
        if (updatedTemplates.length > 0) {
          setSelectedTemplate(updatedTemplates[0].id);
          setContent(updatedTemplates[0].content);
        } else {
          setSelectedTemplate('');
          setContent('');
        }
      }
      message.success(t('templateDeletedSuccess'));
    } catch (error) {
      console.error('删除模板失败:', error);
      message.error(t('templateDeletedFailed'));
    }
  };

  const handleAiQuestionSubmit = async (
    e: React.KeyboardEvent<HTMLTextAreaElement>,
  ) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      if (!aiQuestion.trim()) {
        message.warning(t('enterYourQuestion'));
        return;
      }
      if (!dialogId) {
        message.error(t('noDialogFound'));
        return;
      }
      setIsAiLoading(true);
      const initialCursorPos = cursorPosition;
      const originalContent = content;
      let beforeCursor = '',
        afterCursor = '';
      if (initialCursorPos !== null && showCursorIndicator) {
        beforeCursor = originalContent.substring(0, initialCursorPos);
        afterCursor = originalContent.substring(initialCursorPos);
      }
      const controller = new AbortController();
      const timeoutId = setTimeout(
        () => controller.abort(),
        aiAssistantConfig.api.timeout || 30000,
      );
      try {
        const authorization = localStorage.getItem('Authorization');
        if (!authorization) {
          message.error(t('loginRequiredError'));
          setIsAiLoading(false);
          return;
        }
        const conversationId =
          Math.random().toString(36).substring(2) + Date.now().toString(36);
        await axios.post(
          'v1/conversation/set',
          {
            dialog_id: dialogId,
            name: '文档撰写对话',
            is_new: true,
            conversation_id: conversationId,
            message: [{ role: 'assistant', content: '新对话' }],
          },
          { headers: { authorization }, signal: controller.signal },
        );
        const combinedQuestion = `${aiQuestion}\n\n${t('currentDocumentContextLabel')}:\n${originalContent}`;
        let lastReceivedContent = '';
        const response = await axios.post(
          '/v1/conversation/completion',
          {
            conversation_id: conversationId,
            messages: [{ role: 'user', content: combinedQuestion }],
            knowledge_base_ids:
              selectedKnowledgeBases.length > 0
                ? selectedKnowledgeBases
                : undefined,
            similarity_threshold: similarityThreshold,
            keyword_similarity_weight: keywordSimilarityWeight,
            temperature: modelTemperature,
          },
          {
            timeout: aiAssistantConfig.api.timeout,
            headers: { authorization },
            signal: controller.signal,
          },
        );
        if (response.data) {
          const lines = response.data
            .split('\n')
            .filter((line: string) => line.trim());
          for (let i = 0; i < lines.length; i++) {
            try {
              const jsonStr = lines[i].replace('data:', '').trim();
              const jsonData = JSON.parse(jsonStr);
              if (jsonData.code === 0 && jsonData.data?.answer) {
                const answerChunk = jsonData.data.answer;
                const cleanedAnswerChunk = answerChunk
                  .replace(/<think>[\s\S]*?<\/think>/g, '')
                  .trim();
                const hasUnclosedThink =
                  cleanedAnswerChunk.includes('<think>') &&
                  (!cleanedAnswerChunk.includes('</think>') ||
                    cleanedAnswerChunk.indexOf('<think>') >
                      cleanedAnswerChunk.lastIndexOf('</think>'));
                if (cleanedAnswerChunk && !hasUnclosedThink) {
                  const incrementalContent = cleanedAnswerChunk.substring(
                    lastReceivedContent.length,
                  );
                  if (incrementalContent) {
                    lastReceivedContent = cleanedAnswerChunk;
                    let newFullContent,
                      newCursorPosAfterInsertion = cursorPosition;
                    if (initialCursorPos !== null && showCursorIndicator) {
                      newFullContent =
                        beforeCursor + cleanedAnswerChunk + afterCursor;
                      newCursorPosAfterInsertion =
                        initialCursorPos + cleanedAnswerChunk.length;
                    } else {
                      newFullContent = originalContent + cleanedAnswerChunk;
                      newCursorPosAfterInsertion = newFullContent.length;
                    }
                    setContent(newFullContent);
                    setCursorPosition(newCursorPosAfterInsertion);
                    setTimeout(() => {
                      if (textAreaRef.current) {
                        textAreaRef.current.focus();
                        textAreaRef.current.setSelectionRange(
                          newCursorPosAfterInsertion!,
                          newCursorPosAfterInsertion!,
                        );
                      }
                    }, 0);
                  }
                }
              }
            } catch (parseErr) {
              console.error('解析单行数据失败:', parseErr);
            }
            if (i < lines.length - 1)
              await new Promise((resolve) => {
                setTimeout(resolve, 10);
              });
          }
        }
        await axios.post(
          '/v1/conversation/rm',
          { conversation_ids: [conversationId], dialog_id: dialogId },
          { headers: { authorization } },
        );
      } catch (error: any) {
        console.error('AI助手处理失败:', error);
        if (error.code === 'ECONNABORTED' || error.name === 'AbortError') {
          message.error(t('aiRequestTimeoutError'));
        } else if (error.response?.data?.message) {
          message.error(
            `${t('aiRequestFailedError')}: ${error.response.data.message}`,
          );
        } else {
          message.error(t('aiRequestFailedError'));
        }
      } finally {
        clearTimeout(timeoutId);
        setIsAiLoading(false);
        setAiQuestion('');
        if (textAreaRef.current) textAreaRef.current.focus();
      }
    }
  };

  const handleSave = () => {
    const selectedTemplateItem = templates.find(
      (item) => item.id === selectedTemplate,
    );
    const baseName = selectedTemplateItem
      ? selectedTemplateItem.name
      : t('document', { defaultValue: '文档' });
    const today = new Date();
    const dateStr = `${today.getFullYear()}${String(today.getMonth() + 1).padStart(2, '0')}${String(today.getDate()).padStart(2, '0')}`;
    const fileName = `${baseName}_${dateStr}.docx`;

    if (!content.trim()) {
      message.warning(
        t('emptyContentCannotExport', { defaultValue: '内容为空，无法导出' }),
      );
      return;
    }

    try {
      const tokens = marked.lexer(content) as Token[];
      const paragraphs: Paragraph[] = [];

      function parseTokensToRuns(
        inlineTokens: Tokens.Generic[] | undefined,
      ): TextRun[] {
        const runs: TextRun[] = [];
        if (!inlineTokens) return runs;

        inlineTokens.forEach((token) => {
          if (token.type === 'text') {
            runs.push(new TextRun(token.raw)); // Use raw for exact text
          } else if (
            token.type === 'strong' &&
            'text' in token &&
            typeof token.text === 'string'
          ) {
            runs.push(new TextRun({ text: token.text, bold: true }));
          } else if (
            token.type === 'em' &&
            'text' in token &&
            typeof token.text === 'string'
          ) {
            runs.push(new TextRun({ text: token.text, italics: true }));
          } else if (
            token.type === 'codespan' &&
            'text' in token &&
            typeof token.text === 'string'
          ) {
            runs.push(new TextRun({ text: token.text, style: 'Consolas' }));
          } else if (
            token.type === 'del' &&
            'text' in token &&
            typeof token.text === 'string'
          ) {
            runs.push(new TextRun({ text: token.text, strike: true }));
          } else if (
            token.type === 'link' &&
            'text' in token &&
            typeof token.text === 'string' &&
            'href' in token &&
            typeof token.href === 'string'
          ) {
            runs.push(new TextRun({ text: token.text, style: 'Hyperlink' }));
          } else if ('raw' in token) {
            runs.push(new TextRun(token.raw));
          }
        });
        return runs;
      }

      tokens.forEach((token) => {
        if (token.type === 'heading') {
          const headingToken = token as MarkedHeadingToken;
          let docxHeadingLevel: (typeof HeadingLevel)[keyof typeof HeadingLevel];
          switch (headingToken.depth) {
            case 1:
              docxHeadingLevel = HeadingLevel.HEADING_1;
              break;
            case 2:
              docxHeadingLevel = HeadingLevel.HEADING_2;
              break;
            case 3:
              docxHeadingLevel = HeadingLevel.HEADING_3;
              break;
            case 4:
              docxHeadingLevel = HeadingLevel.HEADING_4;
              break;
            case 5:
              docxHeadingLevel = HeadingLevel.HEADING_5;
              break;
            case 6:
              docxHeadingLevel = HeadingLevel.HEADING_6;
              break;
            default:
              docxHeadingLevel = HeadingLevel.HEADING_1;
          }
          paragraphs.push(
            new Paragraph({
              children: parseTokensToRuns(
                headingToken.tokens ||
                  ([
                    {
                      type: 'text',
                      raw: headingToken.text,
                      text: headingToken.text,
                    },
                  ] as any),
              ),
              heading: docxHeadingLevel,
              spacing: {
                after: 200 - headingToken.depth * 20,
                before: headingToken.depth === 1 ? 0 : 100,
              },
            }),
          );
        } else if (token.type === 'paragraph') {
          const paraToken = token as MarkedParagraphToken;
          const runs = parseTokensToRuns(paraToken.tokens);
          paragraphs.push(
            new Paragraph({
              children: runs.length > 0 ? runs : [new TextRun('')],
              spacing: { after: 120 },
            }),
          );
        } else if (token.type === 'list') {
          const listToken = token as MarkedListToken;
          listToken.items.forEach((listItem: MarkedListItem) => {
            const itemRuns = parseTokensToRuns(listItem.tokens);
            paragraphs.push(
              new Paragraph({
                children: itemRuns.length > 0 ? itemRuns : [new TextRun('')],
                bullet: listToken.ordered ? undefined : { level: 0 },
                numbering: listToken.ordered
                  ? { reference: 'default-numbering', level: 0 }
                  : undefined,
              }),
            );
          });
          paragraphs.push(new Paragraph({ spacing: { after: 80 } }));
        } else if (token.type === 'space') {
          const spaceToken = token as MarkedSpaceToken;
          const newlines = (spaceToken.raw.match(/\n/g) || []).length;
          if (newlines > 1) {
            for (let i = 0; i < newlines; i++)
              paragraphs.push(new Paragraph({}));
          } else {
            paragraphs.push(new Paragraph({ spacing: { after: 80 } }));
          }
        }
      });

      if (paragraphs.length === 0 && content.trim()) {
        paragraphs.push(new Paragraph({ children: [new TextRun(content)] }));
      }

      const doc = new Document({
        numbering: {
          config: [
            {
              reference: 'default-numbering',
              levels: [
                {
                  level: 0,
                  format: 'decimal',
                  text: '%1.',
                  alignment: AlignmentType.LEFT,
                },
              ],
            },
          ],
        },
        sections: [{ properties: {}, children: paragraphs }],
      });

      Packer.toBlob(doc)
        .then((blob) => {
          saveAs(blob, fileName);
          message.success(
            t('exportSuccess', { defaultValue: '文档导出成功!' }),
          );
        })
        .catch((packError) => {
          console.error('Error packing document: ', packError);
          message.error(
            t('exportFailedError', {
              defaultValue: '文档导出失败，请检查控制台日志。',
            }),
          );
        });
    } catch (error) {
      console.error('Error generating Word document: ', error);
      message.error(
        t('exportProcessError', { defaultValue: '处理文档导出时发生错误。' }),
      );
    }
  };

  const renderEditor = () => (
    <Input.TextArea
      ref={textAreaRef}
      style={{
        height: '100%',
        width: '100%',
        border: 'none',
        padding: 24,
        fontSize: 16,
        resize: 'none',
      }}
      value={content}
      onChange={(e) => setContent(e.target.value)}
      onClick={(e) => {
        const target = e.target as HTMLTextAreaElement;
        setCursorPosition(target.selectionStart);
        setShowCursorIndicator(true);
      }}
      onKeyUp={(e) => {
        const target = e.target as HTMLTextAreaElement;
        setCursorPosition(target.selectionStart);
        setShowCursorIndicator(true);
      }}
      placeholder={t('writePlaceholder')}
      autoSize={false}
    />
  );
  const renderPreview = () => (
    <div
      style={{
        height: '100%',
        width: '100%',
        padding: 24,
        overflow: 'auto',
        fontSize: 16,
      }}
    >
      <HightLightMarkdown>
        {content || t('previewPlaceholder')}
      </HightLightMarkdown>
    </div>
  );

  const renderContent = () => {
    switch (viewMode) {
      case 'edit':
        return (
          <div style={{ height: '100%', width: '100%' }}>{renderEditor()}</div>
        );
      case 'preview':
        return (
          <div style={{ height: '100%', width: '100%' }}>{renderPreview()}</div>
        );
      case 'split':
      default:
        return (
          <Flex style={{ height: '100%', width: '100%' }}>
            <div
              style={{
                flex: '1 1 50%',
                borderRight: '1px solid #f0f0f0',
                height: '100%',
                overflow: 'hidden',
              }}
            >
              {renderEditor()}
            </div>
            <div
              style={{ flex: '1 1 50%', height: '100%', overflow: 'hidden' }}
            >
              {renderPreview()}
            </div>
          </Flex>
        );
    }
  };

  return (
    <Layout
      style={{
        height: 'calc(100vh - 80px)',
        display: 'flex',
        flexDirection: 'row',
        overflow: 'hidden',
      }}
    >
      <Sider
        width={320}
        theme="light"
        style={{
          borderRight: '1px solid #f0f0f0',
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        <div
          style={{
            padding: '16px 16px 0 16px',
            height: '70%',
            minHeight: '250px',
            display: 'flex',
            flexDirection: 'column',
          }}
        >
          <Typography.Title
            level={5}
            style={{ textAlign: 'center', marginBottom: 12, flexShrink: 0 }}
          >
            {t('templateList')}
          </Typography.Title>
          <Space
            direction="vertical"
            style={{ width: '100%', marginBottom: 16, flexShrink: 0 }}
          >
            <Button
              type="primary"
              block
              onClick={() => setIsTemplateModalVisible(true)}
            >
              {t('saveCurrentAsTemplate')}
            </Button>
          </Space>
          <div
            style={{
              flexGrow: 1,
              overflowY: 'auto',
              border: '1px solid #f0f0f0',
              borderRadius: '4px',
            }}
          >
            <List
              dataSource={templates}
              locale={{ emptyText: t('noTemplatesAvailable') }}
              renderItem={(item) => (
                <List.Item
                  actions={[
                    <Popconfirm
                      key="delete"
                      title={t('confirmDeleteTemplate')}
                      onConfirm={() => handleDeleteTemplate(item.id)}
                      okText={t('confirm')}
                      cancelText={t('cancel')}
                    >
                      <Button
                        type="text"
                        danger
                        icon={<DeleteOutlined />}
                        size="small"
                      />
                    </Popconfirm>,
                  ]}
                  style={{
                    cursor: 'pointer',
                    background:
                      selectedTemplate === item.id ? '#e6f7ff' : 'transparent',
                    padding: '8px 12px',
                    borderBottom: '1px solid #f0f0f0',
                  }}
                  onClick={() => handleTemplateSelect(item.id)}
                >
                  <Typography.Text
                    ellipsis={{ tooltip: item.name }}
                    style={{ flexGrow: 1, marginRight: 8 }}
                  >
                    {item.name}
                  </Typography.Text>
                  {item.isCustom && (
                    <Typography.Text
                      type="secondary"
                      style={{ fontSize: '0.85em', flexShrink: 0 }}
                    >
                      ({t('customTemplateMarker')})
                    </Typography.Text>
                  )}
                </List.Item>
              )}
            />
          </div>
        </div>
        <Divider style={{ margin: '16px 0', borderTopWidth: '1px' }} />
        <div
          style={{
            padding: '0 16px 16px 16px',
            flexGrow: 1,
            overflowY: 'auto',
          }}
        >
          <Typography.Title
            level={5}
            style={{ textAlign: 'center', marginBottom: 12, flexShrink: 0 }}
          >
            {t('modelConfigurationTitle', { defaultValue: '模型配置' })}
          </Typography.Title>
          <Form layout="vertical" component={false} size="small">
            <Form.Item
              label={t('knowledgeBaseLabel', {
                defaultValue: '知识库 (可多选)',
              })}
              style={{ marginBottom: 12 }}
            >
              <Select
                mode="multiple"
                placeholder={t('knowledgeBasePlaceholderMulti', {
                  defaultValue: '选择一个或多个知识库',
                })}
                value={selectedKnowledgeBases}
                onChange={setSelectedKnowledgeBases}
                allowClear
                style={{ width: '100%' }}
                loading={isLoadingKbs}
                filterOption={(input, option) =>
                  (option?.children?.toString() ?? '')
                    .toLowerCase()
                    .includes(input.toLowerCase())
                }
                maxTagCount="responsive"
                notFoundContent={
                  isLoadingKbs ? null : t('noKnowledgeBaseFound')
                }
              >
                {knowledgeBases.map((kb) => (
                  <Option key={kb.id} value={kb.id}>
                    {kb.name}
                  </Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item
              label={`${t('similarityThresholdLabel')}: ${similarityThreshold.toFixed(2)}`}
              style={{ marginBottom: 12 }}
            >
              <Slider
                min={0}
                max={1}
                step={0.01}
                value={similarityThreshold}
                onChange={setSimilarityThreshold}
                tooltip={{ formatter: (value) => `${value?.toFixed(2)}` }}
              />
            </Form.Item>
            <Form.Item
              label={`${t('keywordSimilarityWeightLabel')}: ${keywordSimilarityWeight.toFixed(2)}`}
              style={{ marginBottom: 12 }}
            >
              <Slider
                min={0}
                max={1}
                step={0.01}
                value={keywordSimilarityWeight}
                onChange={setKeywordSimilarityWeight}
                tooltip={{ formatter: (value) => `${value?.toFixed(2)}` }}
              />
            </Form.Item>
            <Form.Item
              label={`${t('modelTemperatureLabel')}: ${modelTemperature.toFixed(2)}`}
              style={{ marginBottom: 0 }}
            >
              <Slider
                min={0}
                max={2}
                step={0.01}
                value={modelTemperature}
                onChange={setModelTemperature}
                tooltip={{ formatter: (value) => `${value?.toFixed(2)}` }}
              />
            </Form.Item>
          </Form>
        </div>
      </Sider>
      <Content
        style={{
          flexGrow: 1,
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          overflow: 'hidden',
        }}
      >
        <Flex
          vertical
          style={{
            flexGrow: 1,
            gap: 16,
            height: '100%',
            padding: '24px',
            overflow: 'hidden',
          }}
        >
          <Flex
            justify="space-between"
            align="center"
            style={{ flexShrink: 0 }}
          >
            <Typography.Title level={3} style={{ margin: 0 }}>
              {t('writeDocument')}
            </Typography.Title>
            <Space>
              <Button.Group>
                <Button
                  type={viewMode === 'edit' ? 'primary' : 'default'}
                  onClick={() => setViewMode('edit')}
                >
                  {t('edit')}
                </Button>
                <Button
                  type={viewMode === 'split' ? 'primary' : 'default'}
                  onClick={() => setViewMode('split')}
                >
                  {t('split')}
                </Button>
                <Button
                  type={viewMode === 'preview' ? 'primary' : 'default'}
                  onClick={() => setViewMode('preview')}
                >
                  {t('preview')}
                </Button>
              </Button.Group>
              <Button type="primary" onClick={handleSave}>
                {t('saveToWord', { defaultValue: '导出为Word' })}
              </Button>
            </Space>
          </Flex>
          <Card
            bodyStyle={{
              padding: 0,
              height: '100%',
              overflow: 'hidden',
              display: 'flex',
            }}
            style={{
              flexGrow: 1,
              display: 'flex',
              flexDirection: 'column',
              minHeight: 0,
            }}
          >
            {renderContent()}
          </Card>
          <Card
            title={t('aiAssistant')}
            bodyStyle={{
              padding: '12px',
              display: 'flex',
              flexDirection: 'column',
              gap: 10,
            }}
            style={{ flexShrink: 0 }}
          >
            {isAiLoading && (
              <div style={{ textAlign: 'center', marginBottom: 8 }}>
                {t('aiLoadingMessage')}...
              </div>
            )}
            <Input.TextArea
              placeholder={t('askAI')}
              autoSize={{ minRows: 2, maxRows: 5 }}
              value={aiQuestion}
              onChange={(e) => setAiQuestion(e.target.value)}
              onKeyDown={handleAiQuestionSubmit}
              disabled={isAiLoading}
            />
          </Card>
        </Flex>
      </Content>
      <Modal
        title={t('saveAsCustomTemplateTitle')}
        open={isTemplateModalVisible}
        onOk={handleSaveTemplate}
        onCancel={() => {
          setIsTemplateModalVisible(false);
          setTemplateName('');
        }}
        okText={t('saveTemplate')}
        cancelText={t('cancel')}
      >
        <Form layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item label={t('templateNameLabel')} required>
            <Input
              placeholder={t('templateNamePlaceholder')}
              value={templateName}
              onChange={(e) => setTemplateName(e.target.value)}
            />
          </Form.Item>
          <Form.Item label={t('templateContentPreviewLabel')}>
            <Input.TextArea value={content} disabled rows={6} />
          </Form.Item>
        </Form>
      </Modal>
    </Layout>
  );
};

export default Write;
