import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react';
import CodeMirror from '@uiw/react-codemirror';
import { history } from '@codemirror/commands';
import { oneDark } from '@codemirror/theme-one-dark';
import type { FileTab } from '../types';
import { useEditorInstanceManager, useEditorCleanup } from './index';
import { getLanguage } from '../utils/fileTypeUtils';
import { loadLanguage } from './lazyLanguageLoader';
import { useDiffDecorations } from './DiffDecorations';

import type { Extension } from '@codemirror/state';

const LARGE_FILE_THRESHOLD = 100 * 1024;

interface CodeEditorProps {
  instanceId: string;
  tab: FileTab;
  canEdit?: boolean;
  onContentChange: (tabId: string, content: string) => void;
  onSave: (tab: FileTab) => void;
}

const CodeEditor: React.FC<CodeEditorProps> = ({
  instanceId,
  tab,
  canEdit = true,
  onContentChange,
  onSave,
}) => {
  const { addTimer, removeTimer, cleanup } = useEditorInstanceManager(instanceId);
  const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const language = getLanguage(tab.name) || 'javascript';
  const [languageExtension, setLanguageExtension] = useState<Extension | null>(null);
  const [loading, setLoading] = useState(true);

  const { extensions: diffExtensions, hasPendingDiff } = useDiffDecorations(tab.path);

  const isLargeFile = tab.content.length > LARGE_FILE_THRESHOLD;

  useEffect(() => {
    const loadLangExtension = async () => {
      setLoading(true);
      const ext = await loadLanguage(language);
      setLanguageExtension(ext);
      setLoading(false);
    };
    
    loadLangExtension();
  }, [language]);

  const extensions = useMemo(() => {
    const exts: Extension[] = [history(), oneDark];
    if (!isLargeFile) {
      exts.push(...diffExtensions);
    }
    if (languageExtension) {
      exts.unshift(languageExtension);
    }
    return exts;
  }, [languageExtension, diffExtensions, isLargeFile]);

  const handleChange = useCallback((value: string) => {
    onContentChange(tab.id, value);
    
    if (saveTimeoutRef.current) {
      removeTimer(saveTimeoutRef.current);
    }
    saveTimeoutRef.current = addTimer(setTimeout(() => {
      if (tab.isModified) {
        onSave(tab);
      }
    }, 500));
  }, [tab.id, tab.isModified, onContentChange, onSave, addTimer, removeTimer]);

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        onSave(tab);
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, [tab, onSave]);

  useEditorCleanup(instanceId, cleanup);

  if (loading) {
    return (
      <div style={{ 
        display: 'flex', 
        alignItems: 'center', 
        justifyContent: 'center', 
        height: '100%',
        background: '#1e1e1e',
        color: '#888'
      }}>
        加载编辑器...
      </div>
    );
  }

  return (
    <div className="doc-editor-wrapper" style={{ height: '100%', overflow: 'hidden', background: '#1e1e1e', display: 'flex', flexDirection: 'column' }}>
      {hasPendingDiff && (
        <div style={{
          padding: '6px 12px',
          background: 'rgba(33, 150, 243, 0.1)',
          borderBottom: '1px solid rgba(33, 150, 243, 0.25)',
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          flexShrink: 0,
        }}>
          <span style={{ fontSize: 12, color: '#64b5f6' }}>ℹ</span>
          <span style={{ fontSize: 12, color: 'var(--text-200)' }}>
            此文件有未确认的变更，请在消息区查看产物汇总并确认
          </span>
        </div>
      )}
      <CodeMirror
        value={tab.content}
        height="100%"
        extensions={extensions}
        onChange={handleChange}
        theme="dark"
        editable={canEdit}
        style={{ 
          flex: 1,
          minHeight: 0,
          fontSize: 13,
          fontFamily: 'Consolas, Monaco, "Courier New", monospace',
        }}
        basicSetup={{
          lineNumbers: true,
          highlightActiveLineGutter: !isLargeFile,
          highlightSpecialChars: true,
          history: true,
          foldGutter: !isLargeFile,
          drawSelection: true,
          dropCursor: !isLargeFile,
          allowMultipleSelections: !isLargeFile,
          indentOnInput: !isLargeFile,
          syntaxHighlighting: true,
          bracketMatching: !isLargeFile,
          closeBrackets: !isLargeFile,
          autocompletion: !isLargeFile,
          rectangularSelection: !isLargeFile,
          crosshairCursor: false,
          highlightActiveLine: !isLargeFile,
          highlightSelectionMatches: !isLargeFile,
        }}
      />
    </div>
  );
};

export default CodeEditor;
