import React, { useMemo, useState } from "react";
import { ChevronRight } from "lucide-react";
import type { ThinkingTimelineEntry } from "../../../types/chatStream";
import { cn } from "../../../utils/classNames";

interface AssistantThinkingSummaryProps {
  label: string;
  timeline?: ThinkingTimelineEntry[];
  isActive?: boolean;
  defaultExpanded?: boolean;
}

const visibleEntries = (timeline: ThinkingTimelineEntry[]) => (
  timeline.filter((entry) => {
    if (entry.kind === 'tool') return entry.label.trim();
    if (entry.kind === 'work_step') return entry.label.trim();
    return false;
  })
);

const entryLabel = (entry: ThinkingTimelineEntry) => entry.label;

const entryState = (entry: ThinkingTimelineEntry) => {
  if (entry.kind === 'tool' || entry.kind === 'work_step') return entry.state;
  return 'done';
};

const isReasoningEntry = (entry: ThinkingTimelineEntry) => (
  entry.kind === 'work_step' && entry.source === 'reasoning_summary'
);

const compactLabel = (label: string) => {
  const normalized = label.replace(/\s+/g, ' ').trim();
  if (normalized.length <= 150) return normalized;
  const boundary = normalized.lastIndexOf(' ', 146);
  return `${normalized.slice(0, boundary > 48 ? boundary : 147).trim()}...`;
};

// Marker shown on the timeline rail for a tool / work step.
const StepMarker = ({ state }: { state: 'running' | 'done' | 'error' }) => {
  if (state === 'running') {
    return (
      <span className="flex h-4 w-4 items-center justify-center rounded-full bg-app-surface ring-1 ring-brand">
        <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-brand" />
      </span>
    );
  }
  if (state === 'error') {
    return (
      <span className="flex h-4 w-4 items-center justify-center rounded-full bg-danger text-white">
        <svg viewBox="0 0 12 12" className="h-2 w-2" aria-hidden="true">
          <path d="m3.5 3.5 5 5m0-5-5 5" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" />
        </svg>
      </span>
    );
  }
  return (
    <span className="flex h-4 w-4 items-center justify-center rounded-full border border-app-border-strong bg-app-surface text-app-muted">
      <svg viewBox="0 0 12 12" className="h-2.5 w-2.5" aria-hidden="true">
        <path d="M3 6.1 5.1 8.2 9 3.8" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    </span>
  );
};

const AssistantThinkingSummary: React.FC<AssistantThinkingSummaryProps> = ({
  label,
  timeline = [],
  isActive = false,
  defaultExpanded = false,
}) => {
  const [isExpandedState, setIsExpanded] = useState(defaultExpanded);

  const entries = useMemo(() => visibleEntries(timeline), [timeline]);
  const latestReasoningIndex = useMemo(() => {
    for (let index = entries.length - 1; index >= 0; index -= 1) {
      if (isReasoningEntry(entries[index])) return index;
    }
    return -1;
  }, [entries]);
  const isCollapsible = !isActive && entries.length > 0;
  const isExpanded = isActive || isExpandedState;

  return (
    <div className="mb-4" data-testid="working-timeline">
      <button
        type="button"
        aria-expanded={isCollapsible ? isExpanded : undefined}
        disabled={!isCollapsible}
        className={cn(
          'flex items-center gap-2 text-left transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand',
          // Only the collapsible (finished) header reads as a clickable chip.
          isCollapsible && 'group -ml-2 rounded-md px-2 py-1 hover:bg-app-surface-hover',
        )}
        onClick={() => {
          if (!isCollapsible) return;
          setIsExpanded((prev) => !prev);
        }}
      >
        {isActive ? (
          <span className="h-3.5 w-3.5 shrink-0 animate-spin rounded-full border-2 border-app-border border-t-brand" aria-hidden="true" />
        ) : (
          <ChevronRight
            aria-hidden="true"
            className={cn(
              'h-4 w-4 shrink-0 text-app-muted transition-transform duration-150',
              isExpanded && 'rotate-90',
              isCollapsible && 'group-hover:text-app-text',
            )}
          />
        )}
        <span
          className={
            isActive
              ? 'text-gradient-gray text-sm font-medium'
              : 'text-sm font-medium text-app-muted transition-colors group-hover:text-app-text'
          }
        >
          {label}
        </span>
      </button>

      {isExpanded && entries.length > 0 && (
        <div
          className={cn(
            'relative mt-3 space-y-3 pl-6',
            // While working, cap the height and let older steps fade upward into
            // themselves rather than growing without bound.
            isActive && 'fade-mask-top flex max-h-56 flex-col justify-end overflow-hidden',
          )}
        >
          <span className="absolute bottom-2 left-2 top-2 w-px bg-app-border" aria-hidden="true" />
          {entries.map((entry, index) => {
            const state = entryState(entry);
            const isReasoning = isReasoningEntry(entry);
            const isLatestActiveReasoning = isActive && isReasoning && index === latestReasoningIndex;
            return (
              <div key={entry.id} data-testid="working-step" className="relative flex items-start text-[0.9rem] leading-relaxed">
                <span className="absolute -left-6 top-[3px] flex w-4 items-center justify-center" aria-hidden="true">
                  {isReasoning ? (
                    <span className="h-1.5 w-1.5 rounded-full bg-app-border-strong" />
                  ) : (
                    <StepMarker state={state} />
                  )}
                </span>
                <span
                  className={
                    state === 'error'
                      ? 'text-danger-text'
                      : isLatestActiveReasoning
                        ? 'text-gradient-gray font-medium'
                        : isReasoning
                          ? 'text-app-text'
                          : 'text-app-muted'
                  }
                >
                  {compactLabel(entryLabel(entry))}
                </span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

export default React.memo(AssistantThinkingSummary);
