/**
 * 代码执行插件组件
 * 使用 CodeMirror 编辑器 + 终端输出面板 + 交互式输入
 */
import { useState, useRef, useEffect } from 'react';
import { Button, Space, Input, Typography } from 'antd';
import {
  PlayCircleOutlined,
  StopOutlined,
  ClearOutlined,
  CodeOutlined
} from '@ant-design/icons';
import CodeMirror from '@uiw/react-codemirror';
import { python } from '@codemirror/lang-python';
import api from '../../services/api';

const { Text } = Typography;

const CodeExecutor = ({ initialCode = '' }) => {
  const [code, setCode] = useState(initialCode);
  const [output, setOutput] = useState([]);
  const [isRunning, setIsRunning] = useState(false);
  const [needsInput, setNeedsInput] = useState(false);
  const [contextId, setContextId] = useState(null);
  const [userInput, setUserInput] = useState('');
  const outputEndRef = useRef(null);

  useEffect(() => {
    if (initialCode) setCode(initialCode);
  }, [initialCode]);

  useEffect(() => {
    outputEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [output]);

  const appendOutput = (type, text) => {
    setOutput(prev => [...prev, { type, text }]);
  };

  const handleRun = async () => {
    if (!code.trim()) return;
    setIsRunning(true);
    setNeedsInput(false);
    setOutput([{ type: 'info', text: '>>> 运行中...' }]);

    try {
      const res = await api.post('/code/execute', { code });

      if (!res.success) {
        appendOutput('error', res.error || '执行失败');
        if (res.traceback) appendOutput('error', res.traceback);
        setIsRunning(false);
        return;
      }

      // 显示初始输出
      if (res.output) {
        appendOutput('stdout', res.output);
      }

      if (res.needsInput) {
        // 代码需要交互输入
        setContextId(res.context_id);
        setNeedsInput(true);
      } else {
        // 代码直接执行完了
        appendOutput('info', '>>> 执行完成');
        setIsRunning(false);
      }
    } catch (error) {
      appendOutput('error', `错误: ${error.message}`);
      setIsRunning(false);
    }
  };

  const handleInput = async () => {
    if (!contextId) return;

    const inputText = userInput;
    appendOutput('input', `<<< ${inputText}`);
    setUserInput('');
    setNeedsInput(false);

    try {
      const res = await api.post('/code/input', {
        context_id: contextId,
        input: inputText
      });

      if (!res.success) {
        appendOutput('error', res.error || '输入处理失败');
        if (res.traceback) appendOutput('error', res.traceback);
        setIsRunning(false);
        setContextId(null);
        return;
      }

      if (res.output) {
        appendOutput('stdout', res.output);
      }

      if (res.needsInput) {
        // 还需要更多输入
        setNeedsInput(true);
      } else {
        // 执行完成
        appendOutput('info', '>>> 执行完成');
        setIsRunning(false);
        setContextId(null);
      }
    } catch (error) {
      appendOutput('error', `错误: ${error.message}`);
      setIsRunning(false);
      setContextId(null);
    }
  };

  const handleStop = async () => {
    if (contextId) {
      try {
        const res = await api.post('/code/stop', { context_id: contextId });
        if (res.output) {
          appendOutput('stdout', res.output);
        }
      } catch (e) { /* ignore */ }
    }
    appendOutput('warning', '>>> 已终止');
    setIsRunning(false);
    setNeedsInput(false);
    setContextId(null);
  };

  const handleClear = () => {
    setOutput([]);
  };

  const getOutputColor = (type) => {
    switch (type) {
      case 'error': return '#ef4444';
      case 'warning': return '#f59e0b';
      case 'input': return '#10b981';
      case 'info': return '#6b7280';
      default: return '#e5e7eb';
    }
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', gap: '8px' }}>
      {/* 工具栏 */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <Text strong style={{ fontSize: '13px' }}>
          <CodeOutlined /> Python 编辑器
        </Text>
        <Space size="small">
          {!isRunning ? (
            <Button
              type="primary"
              size="small"
              icon={<PlayCircleOutlined />}
              onClick={handleRun}
              style={{ background: '#10b981', borderColor: '#10b981' }}
            >
              运行
            </Button>
          ) : (
            <Button
              danger
              size="small"
              icon={<StopOutlined />}
              onClick={handleStop}
            >
              停止
            </Button>
          )}
          <Button
            size="small"
            icon={<ClearOutlined />}
            onClick={handleClear}
          >
            清除
          </Button>
        </Space>
      </div>

      {/* 代码编辑器 */}
      <div style={{
        flex: '0 0 auto',
        maxHeight: '45%',
        overflow: 'auto',
        borderRadius: '6px',
        border: '1px solid rgba(0,0,0,0.1)'
      }}>
        <CodeMirror
          value={code}
          height="auto"
          minHeight="120px"
          maxHeight="300px"
          extensions={[python()]}
          onChange={(val) => setCode(val)}
          theme="light"
          basicSetup={{
            lineNumbers: true,
            highlightActiveLine: true,
            foldGutter: true,
          }}
        />
      </div>

      {/* 终端输出 */}
      <div style={{
        flex: 1,
        minHeight: '120px',
        background: '#1e1e1e',
        borderRadius: '6px',
        padding: '12px',
        overflow: 'auto',
        fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
        fontSize: '13px',
      }}>
        {output.map((line, i) => (
          <div key={i} style={{ color: getOutputColor(line.type), lineHeight: '1.6', whiteSpace: 'pre-wrap' }}>
            {line.text}
          </div>
        ))}
        {needsInput && (
          <div style={{ display: 'flex', gap: '8px', marginTop: '8px', alignItems: 'center' }}>
            <span style={{ color: '#10b981', flexShrink: 0 }}>{'>>>'}</span>
            <Input
              size="small"
              value={userInput}
              onChange={e => setUserInput(e.target.value)}
              onPressEnter={handleInput}
              placeholder="输入内容后按回车..."
              style={{
                flex: 1,
                background: '#2d2d2d',
                border: '1px solid #444',
                color: '#e5e7eb',
                fontFamily: 'monospace'
              }}
              autoFocus
            />
          </div>
        )}
        <div ref={outputEndRef} />
      </div>
    </div>
  );
};

export default CodeExecutor;
