/**
 * 按任务分组的日志展示组件。
 *
 * - 顶部：任务执行时间线概览（可点击跳转）
 * - 中部：按任务代码过滤搜索框
 * - 主体：Collapse 折叠面板，每个任务一个区块
 * - 展开后显示该任务的完整日志（时间戳、级别、消息）
 *
 * 需求: 10.2, 10.5, 10.6
 */

import React, { useMemo, useRef, useCallback, useState } from "react";
import {
  Collapse,
  Timeline,
  Tag,
  Input,
  Empty,
  Badge,
  Space,
  Typography,
} from "antd";
import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  ClockCircleOutlined,
  QuestionCircleOutlined,
  SearchOutlined,
} from "@ant-design/icons";
import {
  groupLogsByTask,
  filterTaskGroups,
  type TaskLogGroup,
  type ParsedLogEntry,
} from "../utils/taskLogParser";

const { Text } = Typography;

/* ------------------------------------------------------------------ */
/*  状态 → 颜色/图标映射                                               */
/* ------------------------------------------------------------------ */

const STATUS_CONFIG: Record<
  TaskLogGroup["status"],
  { color: string; icon: React.ReactNode; label: string }
> = {
  success: { color: "green", icon: <CheckCircleOutlined />, label: "成功" },
  failed: { color: "red", icon: <CloseCircleOutlined />, label: "失败" },
  running: { color: "blue", icon: <ClockCircleOutlined />, label: "运行中" },
  unknown: { color: "default", icon: <QuestionCircleOutlined />, label: "未知" },
};

const LEVEL_COLOR: Record<string, string> = {
  ERROR: "#ff4d4f",
  CRITICAL: "#ff4d4f",
  WARNING: "#faad14",
  INFO: "#52c41a",
  DEBUG: "#8c8c8c",
};

/* ------------------------------------------------------------------ */
/*  日志级别标签                                                       */
/* ------------------------------------------------------------------ */

const LevelTag: React.FC<{ level: string }> = ({ level }) => (
  <span
    style={{
      color: LEVEL_COLOR[level] ?? "#8c8c8c",
      fontWeight: level === "ERROR" || level === "CRITICAL" ? 600 : 400,
      fontFamily: "monospace",
      fontSize: 12,
      minWidth: 56,
      display: "inline-block",
    }}
  >
    {level}
  </span>
);

/* ------------------------------------------------------------------ */
/*  单条日志行                                                         */
/* ------------------------------------------------------------------ */

const LogLine: React.FC<{ entry: ParsedLogEntry }> = ({ entry }) => (
  <div
    style={{
      fontFamily: "'Cascadia Code', 'Fira Code', Consolas, monospace",
      fontSize: 12,
      lineHeight: 1.7,
      padding: "1px 0",
      whiteSpace: "pre-wrap",
      wordBreak: "break-all",
    }}
  >
    {entry.timestamp && (
      <Text type="secondary" style={{ fontSize: 12, marginRight: 8, fontFamily: "monospace" }}>
        {entry.timestamp}
      </Text>
    )}
    <LevelTag level={entry.level} />
    <span style={{ marginLeft: 8 }}>{entry.message}</span>
  </div>
);

/* ------------------------------------------------------------------ */
/*  任务面板头部                                                       */
/* ------------------------------------------------------------------ */

const TaskPanelHeader: React.FC<{ group: TaskLogGroup }> = ({ group }) => {
  const cfg = STATUS_CONFIG[group.status];
  return (
    <Space size={12}>
      <Text strong style={{ fontFamily: "monospace" }}>{group.taskCode}</Text>
      <Tag color={cfg.color} icon={cfg.icon}>{cfg.label}</Tag>
      <Text type="secondary" style={{ fontSize: 12 }}>
        {group.entries.length} 条日志
      </Text>
      {group.counts.error > 0 && (
        <Badge count={group.counts.error} size="small" title="错误数" />
      )}
      {group.counts.warning > 0 && (
        <Badge
          count={group.counts.warning}
          size="small"
          color="#faad14"
          title="警告数"
        />
      )}
      {group.startTime && (
        <Text type="secondary" style={{ fontSize: 11 }}>
          {group.startTime}
          {group.endTime && group.endTime !== group.startTime
            ? ` → ${group.endTime}`
            : ""}
        </Text>
      )}
    </Space>
  );
};

/* ------------------------------------------------------------------ */
/*  时间线概览                                                         */
/* ------------------------------------------------------------------ */

const TaskTimeline: React.FC<{
  groups: TaskLogGroup[];
  onClickTask: (taskCode: string) => void;
}> = ({ groups, onClickTask }) => {
  if (groups.length === 0) return null;

  const items = groups.map((g) => {
    const cfg = STATUS_CONFIG[g.status];
    return {
      color: cfg.color === "default" ? "gray" : cfg.color,
      children: (
        <div
          style={{ cursor: "pointer" }}
          onClick={() => onClickTask(g.taskCode)}
          role="button"
          tabIndex={0}
          onKeyDown={(e) => {
            if (e.key === "Enter") onClickTask(g.taskCode);
          }}
        >
          <Space size={8}>
            <Text strong style={{ fontFamily: "monospace", fontSize: 13 }}>
              {g.taskCode}
            </Text>
            <Tag color={cfg.color} style={{ fontSize: 11 }}>
              {cfg.label}
            </Tag>
            {g.startTime && (
              <Text type="secondary" style={{ fontSize: 11 }}>
                {g.startTime}
                {g.endTime && g.endTime !== g.startTime
                  ? ` → ${g.endTime}`
                  : ""}
              </Text>
            )}
            <Text type="secondary" style={{ fontSize: 11 }}>
              ({g.entries.length} 条)
            </Text>
          </Space>
        </div>
      ),
    };
  });

  return (
    <div style={{ marginBottom: 12, padding: "8px 12px", background: "#fafafa", borderRadius: 4 }}>
      <Text type="secondary" style={{ fontSize: 12, marginBottom: 8, display: "block" }}>
        任务执行时间线（点击跳转）
      </Text>
      <Timeline items={items} style={{ marginBottom: 0, paddingTop: 8 }} />
    </div>
  );
};

/* ------------------------------------------------------------------ */
/*  主组件                                                             */
/* ------------------------------------------------------------------ */

export interface TaskLogViewerProps {
  /** 原始日志行数组 */
  lines: string[];
}

const TaskLogViewer: React.FC<TaskLogViewerProps> = ({ lines }) => {
  const [taskFilter, setTaskFilter] = useState("");
  const [activeKeys, setActiveKeys] = useState<string[]>([]);
  const panelRefs = useRef<Record<string, HTMLDivElement | null>>({});

  // 解析并分组
  const allGroups = useMemo(() => groupLogsByTask(lines), [lines]);
  const filteredGroups = useMemo(
    () => filterTaskGroups(allGroups, taskFilter),
    [allGroups, taskFilter],
  );

  // 点击时间线跳转到对应任务面板
  const handleTimelineClick = useCallback((taskCode: string) => {
    // 展开目标面板
    setActiveKeys((prev) =>
      prev.includes(taskCode) ? prev : [...prev, taskCode],
    );
    // 滚动到面板位置
    requestAnimationFrame(() => {
      const el = panelRefs.current[taskCode];
      if (el) {
        el.scrollIntoView({ behavior: "smooth", block: "start" });
      }
    });
  }, []);

  const setPanelRef = useCallback(
    (taskCode: string) => (el: HTMLDivElement | null) => {
      panelRefs.current[taskCode] = el;
    },
    [],
  );

  if (lines.length === 0) {
    return <Empty description="暂无日志数据" />;
  }

  // 如果没有可解析的任务分组（全是无法解析的行），回退到普通展示
  if (allGroups.length === 0) {
    return <Empty description="无法解析任务分组" />;
  }

  const collapseItems = filteredGroups.map((group) => ({
    key: group.taskCode,
    label: <TaskPanelHeader group={group} />,
    children: (
      <div
        style={{
          maxHeight: 400,
          overflow: "auto",
          background: "#1e1e1e",
          color: "#d4d4d4",
          padding: 12,
          borderRadius: 4,
        }}
      >
        {group.entries.map((entry, i) => (
          <LogLine key={i} entry={entry} />
        ))}
      </div>
    ),
  }));

  return (
    <div>
      {/* 时间线概览 */}
      <TaskTimeline groups={allGroups} onClickTask={handleTimelineClick} />

      {/* 任务代码过滤 */}
      {allGroups.length > 1 && (
        <div style={{ marginBottom: 12 }}>
          <Input
            prefix={<SearchOutlined />}
            placeholder="按任务代码过滤..."
            value={taskFilter}
            onChange={(e) => setTaskFilter(e.target.value)}
            allowClear
            style={{ width: 280 }}
          />
          <Text type="secondary" style={{ marginLeft: 12, fontSize: 12 }}>
            {filteredGroups.length} / {allGroups.length} 个任务
          </Text>
        </div>
      )}

      {/* 折叠面板 */}
      {filteredGroups.length === 0 ? (
        <Empty description="无匹配的任务" />
      ) : (
        <>
          {filteredGroups.map((g) => (
            <div key={g.taskCode} ref={setPanelRef(g.taskCode)} />
          ))}
          <Collapse
            activeKey={activeKeys}
            onChange={(keys) => setActiveKeys(keys as string[])}
            items={collapseItems}
          />
        </>
      )}
    </div>
  );
};

export default TaskLogViewer;
