import { useState, useEffect } from 'react';
import {
  Input,
  Button,
  Select,
  List,
  Typography,
  Space,
  message,
  Slider,
  Divider,
  Collapse,
  Progress,
  Card,
  Alert,
} from 'antd';
import {
  SearchOutlined,
  HistoryOutlined,
  ReloadOutlined,
  LoadingOutlined,
  FileImageOutlined,
  FileTextOutlined,
  CodeOutlined,
} from '@ant-design/icons';
import type { AttributeDAG, CategoryMode, PromptLanguage } from '../types';
import { getModels } from '../services/api';
import { CategorySelector } from './CategorySelector';

interface DAGProgress {
  step: 'idle' | 'step0' | 'step1' | 'relationships' | 'done' | 'error';
  message: string;
  error?: string;
}

interface DAGHistoryItem {
  query: string;
  result: AttributeDAG;
  timestamp: Date;
}

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

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

interface InputPanelProps {
  loading: boolean;
  progress: DAGProgress;
  history: DAGHistoryItem[];
  currentResult: AttributeDAG | null;
  onAnalyze: (
    query: string,
    model?: string,
    temperature?: number,
    chainCount?: number,
    categoryMode?: CategoryMode,
    customCategories?: string[],
    suggestedCategoryCount?: number,
    lang?: PromptLanguage
  ) => Promise<void>;
  onLoadHistory: (item: DAGHistoryItem, lang?: PromptLanguage) => void;
  onResetView?: () => void;
  visualSettings: VisualSettings;
  onVisualSettingsChange: (settings: VisualSettings) => void;
  lang?: PromptLanguage;
}

export function InputPanel({
  loading,
  progress,
  history,
  currentResult,
  onAnalyze,
  onLoadHistory,
  onResetView,
  visualSettings,
  onVisualSettingsChange,
  lang = 'zh',
}: 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);
  // Category settings
  const [categoryMode, setCategoryMode] = useState<CategoryMode>('dynamic_auto' as CategoryMode);
  const [customCategories, setCustomCategories] = useState<string[]>([]);
  const [suggestedCategoryCount, setSuggestedCategoryCount] = useState(3);

  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(lang === 'zh' ? '請輸入查詢內容' : 'Please enter a query');
      return;
    }

    try {
      await onAnalyze(
        query.trim(),
        selectedModel,
        temperature,
        chainCount,
        categoryMode,
        customCategories.length > 0 ? customCategories : undefined,
        suggestedCategoryCount,
        lang
      );
      setQuery('');
    } catch {
      message.error(lang === 'zh' ? '分析失敗' : '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.query || 'dag'}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

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

    // Group nodes by category
    const nodesByCategory: Record<string, string[]> = {};
    for (const node of currentResult.nodes) {
      if (!nodesByCategory[node.category]) {
        nodesByCategory[node.category] = [];
      }
      nodesByCategory[node.category].push(node.name);
    }

    let markdown = `# ${currentResult.query}\n\n`;
    for (const cat of currentResult.categories) {
      const nodes = nodesByCategory[cat.name] || [];
      markdown += `## ${cat.name}\n`;
      for (const name of nodes) {
        markdown += `- ${name}\n`;
      }
      markdown += '\n';
    }

    const blob = new Blob([markdown], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${currentResult.query || 'dag'}.md`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleExportSVG = () => {
    const reactFlowWrapper = document.querySelector('.react-flow');
    if (!reactFlowWrapper) {
      message.warning('No mindmap to export');
      return;
    }

    const viewport = reactFlowWrapper.querySelector('.react-flow__viewport');
    if (!viewport) {
      message.warning('No mindmap to export');
      return;
    }

    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('width', String(reactFlowWrapper.clientWidth));
    svg.setAttribute('height', String(reactFlowWrapper.clientHeight));
    svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');

    const viewportClone = viewport.cloneNode(true) as SVGGElement;
    svg.appendChild(viewportClone);

    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?.query || 'dag'}.svg`;
    a.click();
    URL.revokeObjectURL(url);
  };

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

    const viewport = reactFlowWrapper.querySelector('.react-flow__viewport');
    if (!viewport) {
      message.warning('No mindmap to export');
      return;
    }

    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('width', String(reactFlowWrapper.clientWidth));
    svg.setAttribute('height', String(reactFlowWrapper.clientHeight));
    svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    svg.appendChild(viewport.cloneNode(true));

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

    img.onload = () => {
      canvas.width = reactFlowWrapper.clientWidth * 2;
      canvas.height = reactFlowWrapper.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?.query || 'dag'}.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 === 'step0'
      ? 15
      : progress.step === 'step1'
        ? 50
        : progress.step === 'relationships'
          ? 85
          : 100;

    return (
      <Alert
        type={progress.step === 'error' ? 'error' : 'info'}
        icon={progress.step === 'error' ? undefined : <LoadingOutlined spin />}
        message={progress.message}
        description={
          <Progress
            percent={Math.round(percent)}
            size="small"
            status={progress.step === 'error' ? 'exception' : 'active'}
            strokeColor={{ from: '#108ee9', to: '#87d068' }}
          />
        }
        style={{ marginBottom: 16 }}
        showIcon
      />
    );
  };

  const collapseItems = [
    {
      key: 'categories',
      label: 'Category Settings',
      children: (
        <CategorySelector
          mode={categoryMode}
          onModeChange={setCategoryMode}
          customCategories={customCategories}
          onCustomCategoriesChange={setCustomCategories}
          suggestedCount={suggestedCategoryCount}
          onSuggestedCountChange={setSuggestedCategoryCount}
          disabled={loading}
        />
      ),
    },
    {
      key: 'llm',
      label: 'LLM Parameters',
      children: (
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          <div>
            <Text type="secondary" style={{ fontSize: 12 }}>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 type="secondary" style={{ fontSize: 12 }}>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%' }} size="middle">
          <div>
            <Text type="secondary" style={{ fontSize: 12 }}>Node Spacing: {visualSettings.nodeSpacing}px</Text>
            <Slider
              min={20}
              max={80}
              value={visualSettings.nodeSpacing}
              onChange={(v) => onVisualSettingsChange({ ...visualSettings, nodeSpacing: v })}
            />
          </div>
          <div>
            <Text type="secondary" style={{ fontSize: 12 }}>Font Size: {visualSettings.fontSize}px</Text>
            <Slider
              min={10}
              max={18}
              value={visualSettings.fontSize}
              onChange={(v) => onVisualSettingsChange({ ...visualSettings, fontSize: v })}
            />
          </div>
          <Button
            icon={<ReloadOutlined />}
            onClick={onResetView}
            disabled={!currentResult}
            block
          >
            Reset View
          </Button>
        </Space>
      ),
    },
    {
      key: 'export',
      label: 'Export',
      children: (
        <Space direction="vertical" style={{ width: '100%' }} size="small">
          <Button.Group style={{ width: '100%' }}>
            <Button
              icon={<FileImageOutlined />}
              onClick={handleExportPNG}
              disabled={!currentResult}
              style={{ flex: 1 }}
            >
              PNG
            </Button>
            <Button
              icon={<FileImageOutlined />}
              onClick={handleExportSVG}
              disabled={!currentResult}
              style={{ flex: 1 }}
            >
              SVG
            </Button>
          </Button.Group>
          <Button.Group style={{ width: '100%' }}>
            <Button
              icon={<CodeOutlined />}
              onClick={handleExportJSON}
              disabled={!currentResult}
              style={{ flex: 1 }}
            >
              JSON
            </Button>
            <Button
              icon={<FileTextOutlined />}
              onClick={handleExportMarkdown}
              disabled={!currentResult}
              style={{ flex: 1 }}
            >
              MD
            </Button>
          </Button.Group>
        </Space>
      ),
    },
  ];

  return (
    <div style={{
      display: 'flex',
      flexDirection: 'column',
      height: '100%',
      padding: 16,
      gap: 16
    }}>
      {/* Main Input Card */}
      <Card
        size="small"
        title={<Text strong>Analyze Object</Text>}
        styles={{ body: { padding: 12 } }}
      >
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          <Select
            style={{ width: '100%' }}
            value={selectedModel}
            onChange={setSelectedModel}
            loading={loadingModels}
            placeholder="Select a model"
            options={models.map((m) => ({ label: m, value: m }))}
            size="middle"
          />
          <TextArea
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyPress={handleKeyPress}
            placeholder="Enter an object to analyze (e.g., umbrella, smartphone)"
            autoSize={{ minRows: 2, maxRows: 4 }}
          />
          <Button
            type="primary"
            icon={<SearchOutlined />}
            onClick={handleAnalyze}
            loading={loading}
            block
            size="large"
          >
            Analyze
          </Button>
        </Space>
      </Card>

      {/* Progress Indicator */}
      {renderProgressIndicator()}

      {/* Settings Collapse */}
      <Collapse
        items={collapseItems}
        defaultActiveKey={[]}
        size="small"
        style={{ background: 'transparent' }}
      />

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

      {/* History Section */}
      <div style={{ flex: 1, overflow: 'auto', minHeight: 0 }}>
        <Title level={5} style={{ marginBottom: 8 }}>
          <HistoryOutlined style={{ marginRight: 8 }} />
          History
        </Title>
        <List
          size="small"
          dataSource={history}
          locale={{ emptyText: 'No history yet' }}
          renderItem={(item) => (
            <List.Item
              style={{
                cursor: 'pointer',
                padding: '8px 12px',
                borderRadius: 6,
                marginBottom: 4,
                transition: 'background 0.2s',
              }}
              onClick={() => onLoadHistory(item, lang)}
              className="history-item"
            >
              <div style={{ flex: 1, minWidth: 0 }}>
                <Text ellipsis style={{ display: 'block' }}>
                  {item.query}
                </Text>
                <Text type="secondary" style={{ fontSize: 11 }}>
                  {item.timestamp.toLocaleTimeString()}
                </Text>
              </div>
            </List.Item>
          )}
        />
      </div>
    </div>
  );
}
