/**
 * KRA - Code Preview Component
 * 代码预览组件 - 支持语法高亮和文件分类展示
 */
import React, { useEffect, useState, useRef, useMemo, useCallback } from 'react';
import { Tabs, Button, Space, message, Empty, Tooltip, Input, Tag } from 'antd';
import {
  CopyOutlined,
  SelectOutlined,
  SearchOutlined,
  FileTextOutlined,
  CodeOutlined,
  Html5Outlined,
  FileOutlined,
} from '@ant-design/icons';
import { Marked } from 'marked';
import { markedHighlight } from 'marked-highlight';
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css';
import styles from './CodePreview.less';

interface CodePreviewProps {
  previewCode: Record<string, string> | null;
  isAdd?: boolean;
}

// 需要在追加模式下过滤的文件
const createKeyFilters = [
  'enter.go',
  'gorm_biz.go',
  'router_biz.go',
  'api',
  'router',
  'initialize',
  'gen.go',
];

// 文件类型图标映射
const getFileIcon = (filename: string) => {
  const ext = filename.split('.').pop()?.toLowerCase();
  switch (ext) {
    case 'go':
      return <CodeOutlined style={{ color: '#00ADD8' }} />;
    case 'tsx':
    case 'ts':
      return <CodeOutlined style={{ color: '#3178C6' }} />;
    case 'jsx':
    case 'js':
      return <CodeOutlined style={{ color: '#F7DF1E' }} />;
    case 'vue':
      return <Html5Outlined style={{ color: '#42B883' }} />;
    case 'less':
    case 'css':
    case 'scss':
      return <FileTextOutlined style={{ color: '#CC6699' }} />;
    default:
      return <FileOutlined />;
  }
};

// 获取文件类型标签
const getFileTypeTag = (filename: string) => {
  const ext = filename.split('.').pop()?.toLowerCase();
  const typeMap: Record<string, { color: string; label: string }> = {
    go: { color: 'cyan', label: 'Go' },
    tsx: { color: 'blue', label: 'TSX' },
    ts: { color: 'blue', label: 'TS' },
    jsx: { color: 'gold', label: 'JSX' },
    js: { color: 'gold', label: 'JS' },
    vue: { color: 'green', label: 'Vue' },
    less: { color: 'magenta', label: 'Less' },
    css: { color: 'magenta', label: 'CSS' },
    scss: { color: 'magenta', label: 'SCSS' },
  };
  const type = typeMap[ext || ''] || { color: 'default', label: ext?.toUpperCase() || 'FILE' };
  return <Tag color={type.color}>{type.label}</Tag>;
};

// 获取语言类型
const getLanguage = (filename: string): string => {
  const ext = filename.split('.').pop()?.toLowerCase();
  const langMap: Record<string, string> = {
    go: 'go',
    tsx: 'typescript',
    ts: 'typescript',
    jsx: 'javascript',
    js: 'javascript',
    vue: 'html',
    less: 'less',
    css: 'css',
    scss: 'scss',
    json: 'json',
    yaml: 'yaml',
    yml: 'yaml',
    md: 'markdown',
    sql: 'sql',
  };
  return langMap[ext || ''] || 'plaintext';
};

// 文件分类
const categorizeFiles = (files: Record<string, string>) => {
  const categories: Record<string, string[]> = {
    'Biz 层': [],
    'Data 层': [],
    'Service 层': [],
    'Handler 层': [],
    'Router 层': [],
    '前端页面': [],
    '前端服务': [],
    '前端类型': [],
    '其他': [],
  };

  Object.keys(files).forEach((filename) => {
    if (filename.includes('/biz/') || filename.includes('\\biz\\')) {
      categories['Biz 层'].push(filename);
    } else if (filename.includes('/data/') || filename.includes('\\data\\')) {
      categories['Data 层'].push(filename);
    } else if (filename.includes('/service/') || filename.includes('\\service\\')) {
      categories['Service 层'].push(filename);
    } else if (filename.includes('/handler/') || filename.includes('\\handler\\')) {
      categories['Handler 层'].push(filename);
    } else if (filename.includes('/router/') || filename.includes('\\router\\')) {
      categories['Router 层'].push(filename);
    } else if (filename.includes('/pages/') || filename.includes('\\pages\\')) {
      categories['前端页面'].push(filename);
    } else if (filename.includes('/services/') || filename.includes('\\services\\')) {
      categories['前端服务'].push(filename);
    } else if (filename.includes('/types/') || filename.includes('\\types\\')) {
      categories['前端类型'].push(filename);
    } else {
      categories['其他'].push(filename);
    }
  });

  // 过滤空分类
  return Object.fromEntries(
    Object.entries(categories).filter(([_, files]) => files.length > 0)
  );
};

const CodePreview: React.FC<CodePreviewProps> = ({ previewCode, isAdd = false }) => {
  const [activeKey, setActiveKey] = useState<string>('');
  const [searchText, setSearchText] = useState('');
  const contentRefs = useRef<Record<string, HTMLDivElement | null>>({});
  const markedRef = useRef<Marked | null>(null);

  // 过滤后的代码
  const filteredCode = useMemo(() => {
    if (!previewCode) return {};
    
    const result: Record<string, string> = {};
    for (const key in previewCode) {
      // 追加模式下过滤特定文件
      if (isAdd && createKeyFilters.some((filter) => key.includes(filter))) {
        continue;
      }
      // 搜索过滤
      if (searchText && !key.toLowerCase().includes(searchText.toLowerCase())) {
        continue;
      }
      result[key] = previewCode[key];
    }
    return result;
  }, [previewCode, isAdd, searchText]);

  // 文件分类
  const categorizedFiles = useMemo(() => categorizeFiles(filteredCode), [filteredCode]);

  // 初始化 marked
  useEffect(() => {
    markedRef.current = new Marked(
      markedHighlight({
        langPrefix: 'hljs language-',
        highlight(code, lang) {
          const language = hljs.getLanguage(lang) ? lang : 'plaintext';
          return hljs.highlight(code, { language }).value;
        },
      })
    );
  }, []);

  // 渲染代码
  useEffect(() => {
    if (!markedRef.current) return;

    const keys = Object.keys(filteredCode);
    if (keys.length > 0 && !activeKey) {
      setActiveKey(keys[0]);
    }

    // 渲染所有代码块
    keys.forEach((key) => {
      const element = contentRefs.current[key];
      if (element && filteredCode[key]) {
        const lang = getLanguage(key);
        const codeBlock = '```' + lang + '\n' + filteredCode[key] + '\n```';
        element.innerHTML = markedRef.current!.parse(codeBlock) as string;
      }
    });
  }, [filteredCode, activeKey]);

  // 选中当前代码
  const selectText = useCallback(() => {
    const element = contentRefs.current[activeKey];
    if (!element) return;

    if (window.getSelection) {
      const selection = window.getSelection();
      const range = document.createRange();
      range.selectNodeContents(element);
      selection?.removeAllRanges();
      selection?.addRange(range);
    }
  }, [activeKey]);

  // 复制当前代码
  const copyCode = useCallback(() => {
    const code = filteredCode[activeKey];
    if (!code) {
      message.warning('没有可复制的代码');
      return;
    }

    navigator.clipboard.writeText(code).then(
      () => message.success('复制成功'),
      () => message.error('复制失败')
    );
  }, [activeKey, filteredCode]);

  // 复制所有代码
  const copyAllCode = useCallback(() => {
    const allCode = Object.entries(filteredCode)
      .map(([filename, code]) => `// ===== ${filename} =====\n${code}`)
      .join('\n\n');

    navigator.clipboard.writeText(allCode).then(
      () => message.success('复制所有代码成功'),
      () => message.error('复制失败')
    );
  }, [filteredCode]);

  if (!previewCode || Object.keys(filteredCode).length === 0) {
    return (
      <Empty
        description={searchText ? '没有匹配的文件' : '暂无预览代码'}
        className={styles.empty}
      />
    );
  }

  // 构建标签页项
  const tabItems = Object.keys(filteredCode).map((filename) => ({
    key: filename,
    label: (
      <Tooltip title={filename}>
        <span className={styles.tabLabel}>
          {getFileIcon(filename)}
          <span className={styles.filename}>{filename.split(/[/\\]/).pop()}</span>
        </span>
      </Tooltip>
    ),
    children: (
      <div className={styles.codeContainer}>
        <div className={styles.codeHeader}>
          <span className={styles.filepath}>
            {getFileTypeTag(filename)}
            {filename}
          </span>
          <Space>
            <Button
              size="small"
              icon={<SelectOutlined />}
              onClick={selectText}
            >
              全选
            </Button>
            <Button
              size="small"
              type="primary"
              icon={<CopyOutlined />}
              onClick={copyCode}
            >
              复制
            </Button>
          </Space>
        </div>
        <div
          ref={(el) => (contentRefs.current[filename] = el)}
          className={styles.codeContent}
        />
      </div>
    ),
  }));

  return (
    <div className={styles.codePreview}>
      <div className={styles.toolbar}>
        <Input
          placeholder="搜索文件..."
          prefix={<SearchOutlined />}
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          allowClear
          style={{ width: 200 }}
        />
        <Space>
          <span className={styles.fileCount}>
            共 {Object.keys(filteredCode).length} 个文件
          </span>
          <Button icon={<CopyOutlined />} onClick={copyAllCode}>
            复制全部
          </Button>
        </Space>
      </div>

      {/* 文件分类统计 */}
      <div className={styles.categories}>
        {Object.entries(categorizedFiles).map(([category, files]) => (
          <Tag key={category} color="processing">
            {category}: {files.length}
          </Tag>
        ))}
      </div>

      <Tabs
        activeKey={activeKey}
        onChange={setActiveKey}
        tabPosition="left"
        items={tabItems}
        className={styles.tabs}
      />
    </div>
  );
};

export default CodePreview;
