import { useState, useEffect } from 'react';
import {
  Input,
  Button,
  Select,
  List,
  Typography,
  Space,
  message,
  Slider,
  Divider,
  Collapse,
  Progress,
  Tag,
} from 'antd';
import {
  SearchOutlined,
  HistoryOutlined,
  DownloadOutlined,
  ExpandAltOutlined,
  ShrinkOutlined,
  LoadingOutlined,
  CheckCircleOutlined,
} from '@ant-design/icons';
import type { HistoryItem, AttributeNode, StreamProgress } from '../types';
import { getModels } from '../services/api';

const { TextArea } = Input;
const { Text } = Typography;

interface VisualSettings {
  nodeSpacing: number;
  fontSize: number;
}

interface InputPanelProps {
  loading: boolean;
  progress: StreamProgress;
  history: HistoryItem[];
  currentResult: AttributeNode | null;
  onAnalyze: (query: string, model?: string, temperature?: number, chainCount?: number) => Promise<void>;
  onLoadHistory: (item: HistoryItem) => void;
  onExpandAll?: () => void;
  onCollapseAll?: () => void;
  visualSettings: VisualSettings;
  onVisualSettingsChange: (settings: VisualSettings) => void;
}

export function InputPanel({
  loading,
  progress,
  history,
  currentResult,
  onAnalyze,
  onLoadHistory,
  onExpandAll,
  onCollapseAll,
  visualSettings,
  onVisualSettingsChange,
}: InputPanelProps) {
  const [query, setQuery] = useState('');
  const [models, setModels] = useState<string[]>([]);
  const [selectedModel, setSelectedModel] = useState<string | undefined>();
  const [loadingModels, setLoadingModels] = useState(false);
  const [temperature, setTemperature] = useState(0.7);
  const [chainCount, setChainCount] = useState(5);

  useEffect(() => {
    async function fetchModels() {
      setLoadingModels(true);
      try {
        const response = await getModels();
        setModels(response.models);
        if (response.models.length > 0 && !selectedModel) {
          const defaultModel = response.models.find((m) => m.includes('qwen3')) || response.models[0];
          setSelectedModel(defaultModel);
        }
      } catch {
        message.error('Failed to fetch models');
      } finally {
        setLoadingModels(false);
      }
    }

    fetchModels();
  }, []);

  const handleAnalyze = async () => {
    if (!query.trim()) {
      message.warning('Please enter a query');
      return;
    }

    try {
      await onAnalyze(query.trim(), selectedModel, temperature, chainCount);
      setQuery('');
    } catch {
      message.error('Analysis failed');
    }
  };

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleAnalyze();
    }
  };

  const handleExportJSON = () => {
    if (!currentResult) {
      message.warning('No data to export');
      return;
    }
    const json = JSON.stringify(currentResult, null, 2);
    const blob = new Blob([json], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${currentResult.name || 'mindmap'}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleExportMarkdown = () => {
    if (!currentResult) {
      message.warning('No data to export');
      return;
    }

    const nodeToMarkdown = (node: AttributeNode, level: number = 0): string => {
      const indent = '  '.repeat(level);
      let md = `${indent}- ${node.name}\n`;
      if (node.children) {
        node.children.forEach((child) => {
          md += nodeToMarkdown(child, level + 1);
        });
      }
      return md;
    };

    const markdown = `# ${currentResult.name}\n\n${currentResult.children?.map((c) => nodeToMarkdown(c, 0)).join('') || ''}`;
    const blob = new Blob([markdown], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${currentResult.name || 'mindmap'}.md`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleExportSVG = () => {
    const svg = document.querySelector('.mindmap-svg');
    if (!svg) {
      message.warning('No mindmap to export');
      return;
    }
    const svgData = new XMLSerializer().serializeToString(svg);
    const blob = new Blob([svgData], { type: 'image/svg+xml' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${currentResult?.name || 'mindmap'}.svg`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleExportPNG = () => {
    const svg = document.querySelector('.mindmap-svg') as SVGSVGElement;
    if (!svg) {
      message.warning('No mindmap to export');
      return;
    }

    const svgData = new XMLSerializer().serializeToString(svg);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const img = new Image();

    img.onload = () => {
      canvas.width = svg.clientWidth * 2;
      canvas.height = svg.clientHeight * 2;
      ctx?.scale(2, 2);
      ctx?.drawImage(img, 0, 0);
      const pngUrl = canvas.toDataURL('image/png');
      const a = document.createElement('a');
      a.href = pngUrl;
      a.download = `${currentResult?.name || 'mindmap'}.png`;
      a.click();
    };

    img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData)));
  };

  const renderProgressIndicator = () => {
    if (progress.step === 'idle' || progress.step === 'done') return null;

    const percent = progress.step === 'step1'
      ? 10
      : progress.step === 'chains'
        ? 10 + (progress.currentChainIndex / progress.totalChains) * 90
        : 100;

    return (
      <div style={{ marginBottom: 16, padding: 12, background: 'rgba(0,0,0,0.04)', borderRadius: 8 }}>
        <Space direction="vertical" style={{ width: '100%' }}>
          <Space>
            {progress.step === 'error' ? (
              <Tag color="error">Error</Tag>
            ) : (
              <LoadingOutlined spin />
            )}
            <Text>{progress.message}</Text>
          </Space>
          <Progress percent={Math.round(percent)} size="small" status={progress.step === 'error' ? 'exception' : 'active'} />

          {progress.completedChains.length > 0 && (
            <div style={{ marginTop: 8 }}>
              <Text type="secondary" style={{ fontSize: 12 }}>Completed chains:</Text>
              <div style={{ maxHeight: 120, overflow: 'auto', marginTop: 4 }}>
                {progress.completedChains.map((chain, i) => (
                  <div key={i} style={{ fontSize: 11, padding: '2px 0' }}>
                    <CheckCircleOutlined style={{ color: '#52c41a', marginRight: 4 }} />
                    {chain.material} → {chain.function} → {chain.usage} → {chain.user}
                  </div>
                ))}
              </div>
            </div>
          )}
        </Space>
      </div>
    );
  };

  const collapseItems = [
    {
      key: 'llm',
      label: 'LLM Parameters',
      children: (
        <Space direction="vertical" style={{ width: '100%' }}>
          <div>
            <Text>Temperature: {temperature}</Text>
            <Slider
              min={0}
              max={1}
              step={0.1}
              value={temperature}
              onChange={setTemperature}
              marks={{ 0: '0', 0.5: '0.5', 1: '1' }}
            />
          </div>
          <div>
            <Text>Chain Count: {chainCount}</Text>
            <Slider
              min={1}
              max={10}
              step={1}
              value={chainCount}
              onChange={setChainCount}
              marks={{ 1: '1', 5: '5', 10: '10' }}
            />
          </div>
        </Space>
      ),
    },
    {
      key: 'visual',
      label: 'Visual Settings',
      children: (
        <Space direction="vertical" style={{ width: '100%' }}>
          <div>
            <Text>Node Spacing: {visualSettings.nodeSpacing}</Text>
            <Slider
              min={20}
              max={80}
              value={visualSettings.nodeSpacing}
              onChange={(v) => onVisualSettingsChange({ ...visualSettings, nodeSpacing: v })}
            />
          </div>
          <div>
            <Text>Font Size: {visualSettings.fontSize}px</Text>
            <Slider
              min={10}
              max={18}
              value={visualSettings.fontSize}
              onChange={(v) => onVisualSettingsChange({ ...visualSettings, fontSize: v })}
            />
          </div>
          <Space>
            <Button icon={<ExpandAltOutlined />} onClick={onExpandAll} disabled={!currentResult}>
              Expand All
            </Button>
            <Button icon={<ShrinkOutlined />} onClick={onCollapseAll} disabled={!currentResult}>
              Collapse All
            </Button>
          </Space>
        </Space>
      ),
    },
    {
      key: 'export',
      label: 'Export',
      children: (
        <Space wrap>
          <Button icon={<DownloadOutlined />} onClick={handleExportPNG} disabled={!currentResult}>
            PNG
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExportSVG} disabled={!currentResult}>
            SVG
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExportJSON} disabled={!currentResult}>
            JSON
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExportMarkdown} disabled={!currentResult}>
            Markdown
          </Button>
        </Space>
      ),
    },
  ];

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', padding: 16 }}>
      <Space direction="vertical" style={{ width: '100%', marginBottom: 16 }}>
        <Text strong>Model</Text>
        <Select
          style={{ width: '100%' }}
          value={selectedModel}
          onChange={setSelectedModel}
          loading={loadingModels}
          placeholder="Select a model"
          options={models.map((m) => ({ label: m, value: m }))}
        />
      </Space>

      <Space direction="vertical" style={{ width: '100%', marginBottom: 16 }}>
        <Text strong>Input</Text>
        <TextArea
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onKeyPress={handleKeyPress}
          placeholder="Enter an object to analyze (e.g., umbrella)"
          autoSize={{ minRows: 3, maxRows: 6 }}
        />
        <Button
          type="primary"
          icon={<SearchOutlined />}
          onClick={handleAnalyze}
          loading={loading}
          block
        >
          Analyze
        </Button>
      </Space>

      {renderProgressIndicator()}

      <Collapse items={collapseItems} defaultActiveKey={['llm']} size="small" style={{ marginBottom: 16 }} />

      <Divider style={{ margin: '8px 0' }} />

      <div style={{ flex: 1, overflow: 'auto' }}>
        <Text strong>
          <HistoryOutlined /> History
        </Text>
        <List
          size="small"
          dataSource={history}
          locale={{ emptyText: 'No history yet' }}
          renderItem={(item) => (
            <List.Item
              style={{ cursor: 'pointer', padding: '8px 0' }}
              onClick={() => onLoadHistory(item)}
            >
              <Text ellipsis style={{ maxWidth: '100%' }}>
                {item.query}
              </Text>
              <Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>
                {item.timestamp.toLocaleTimeString()}
              </Text>
            </List.Item>
          )}
        />
      </div>
    </div>
  );
}
