import { Timeline, Text, Code, Collapse, Box, Group } from "@mantine/core";
import {
  IconCircleCheck,
  IconCircleX,
  IconLoader,
  IconCircleMinus,
  IconClock,
} from "@tabler/icons-react";
import { useDisclosure } from "@mantine/hooks";
import type { DagStepResult } from "../types";

const iconMap: Record<string, React.ReactNode> = {
  success: <IconCircleCheck size={16} color="var(--mantine-color-green-6)" />,
  failed: <IconCircleX size={16} color="var(--mantine-color-red-6)" />,
  running: <IconLoader size={16} color="var(--mantine-color-blue-6)" />,
  skipped: <IconCircleMinus size={16} color="var(--mantine-color-dimmed)" />,
  pending: <IconClock size={16} color="var(--mantine-color-gray-6)" />,
};

function StepItem({ step }: { step: DagStepResult }) {
  const [opened, { toggle }] = useDisclosure(step.Status === "failed");
  const hasOutput = step.Stdout || step.Stderr;

  return (
    <Timeline.Item
      bullet={iconMap[step.Status] || iconMap.pending}
      title={
        <Group gap="xs">
          <Text
            size="sm"
            fw={500}
            onClick={hasOutput ? toggle : undefined}
            style={hasOutput ? { cursor: "pointer" } : undefined}
          >
            {step.StepName}
          </Text>
          <Text size="xs" c="dimmed">
            {step.DurationMs}ms
          </Text>
          {step.ExitCode !== 0 && step.ExitCode !== -1 && (
            <Text size="xs" c="red">
              exit {step.ExitCode}
            </Text>
          )}
        </Group>
      }
    >
      {hasOutput && (
        <Collapse in={opened}>
          <Box mt="xs">
            {step.Stdout && (
              <Code block mb="xs" style={{ maxHeight: 200, overflow: "auto" }}>
                {step.Stdout}
              </Code>
            )}
            {step.Stderr && (
              <Code
                block
                color="red"
                style={{ maxHeight: 200, overflow: "auto" }}
              >
                {step.Stderr}
              </Code>
            )}
          </Box>
        </Collapse>
      )}
    </Timeline.Item>
  );
}

export function StepTimeline({ steps }: { steps: DagStepResult[] }) {
  const activeIndex = steps.findIndex((s) => s.Status === "running");

  return (
    <Timeline
      active={activeIndex >= 0 ? activeIndex : steps.length - 1}
      bulletSize={24}
    >
      {steps.map((step) => (
        <StepItem key={step.ID} step={step} />
      ))}
    </Timeline>
  );
}
