import { useEffect, useRef } from 'react';
import { CircleCheck, FileText, Image, List, Mic, Video } from 'lucide-react';
import { isParticleDeleted, type Human, type Particle } from '@/api/types';
import { cn } from '@/lib/utils';
import { useNetwork } from '@/hooks/use-networks';
import { resolveHumanDisplay } from '@/lib/humans';
import { RelativeTimestamp } from '@/components/relative-timestamp';
import { HumanAvatar } from '@/components/human-avatar';
import { KeyHint } from '@/components/key-hint';
import { ScrollArea } from '@/components/ui/scroll-area';

interface StreamListSidebarProps {
  items: Particle[];
  networkId: string;
  currentIndex: number;
  onSelect: (index: number) => void;
  onToggle: () => void;
}

/**
 * Browse-mode panel beside the stream: a chat-like timeline of every
 * particle. Selecting a message plays it in the immersive stream view;
 * nothing auto-advances.
 */
export function StreamListSidebar({
  items,
  networkId,
  currentIndex,
  onSelect,
  onToggle,
}: StreamListSidebarProps) {
  const network = useNetwork(networkId);
  const rowRefs = useRef<Array<HTMLDivElement | null>>([]);

  useEffect(() => {
    if (currentIndex >= 0) {
      rowRefs.current[currentIndex]?.scrollIntoView({ block: 'nearest' });
    }
  }, [currentIndex]);

  return (
    <aside className="bg-sidebar text-sidebar-foreground border-border flex w-60 shrink-0 flex-col overflow-hidden border-l">
      <div className="border-border flex shrink-0 items-center gap-2 border-b px-4 py-3">
        <List className="text-muted-foreground size-3.5" />
        <span className="mr-auto truncate text-sm font-medium">
          {items.length} messages
        </span>
        <KeyHint
          keys="L"
          onClick={onToggle}
          title="Hide list (or press L)"
          className="text-muted-foreground text-xs"
        >
          to close
        </KeyHint>
      </div>
      <ScrollArea className="min-h-0 flex-1">
        <div className="flex flex-col gap-0.5 px-2 py-2">
          {items.map((item, index) => (
            <div
              key={item.id}
              ref={(el) => {
                rowRefs.current[index] = el;
              }}
            >
              <ChatRow
                particle={item}
                humans={network?.humans}
                isSelected={index === currentIndex}
                onClick={() => onSelect(index)}
              />
            </div>
          ))}
          {items.length === 0 && (
            <p className="text-muted-foreground px-2 py-8 text-center text-sm">
              No particles in this stream yet.
            </p>
          )}
        </div>
      </ScrollArea>
    </aside>
  );
}

function ChatRow({
  particle,
  humans,
  isSelected,
  onClick,
}: {
  particle: Particle;
  humans: Human[] | undefined;
  isSelected: boolean;
  onClick: () => void;
}) {
  const sender = resolveHumanDisplay(particle.created_by_human_id, humans);

  return (
    <div
      role="button"
      tabIndex={0}
      onClick={onClick}
      // Enter only — Space is reserved for play/pause in the stream view.
      onKeyDown={(e) => {
        if (e.key === 'Enter') onClick();
      }}
      className={cn(
        'flex cursor-pointer items-start gap-2.5 rounded-md px-2 py-2 text-left transition-colors',
        isSelected ? 'bg-accent' : 'hover:bg-accent/50',
      )}
    >
      <HumanAvatar
        size="sm"
        className="mt-0.5 shrink-0"
        initials={sender.initials}
        avatarObjectId={sender.avatarObjectId}
        fallbackClassName="bg-muted text-muted-foreground text-[10px] font-medium"
      />
      <div className="min-w-0 flex-1 overflow-hidden">
        <div className="flex items-baseline justify-between gap-2">
          <span className="truncate text-xs font-semibold">
            {sender.displayName}
          </span>
          <span className="text-muted-foreground shrink-0 text-[10px]">
            <RelativeTimestamp date={particle.created_at} />
          </span>
        </div>
        <ChatRowContent particle={particle} />
      </div>
    </div>
  );
}

function ChatRowContent({ particle }: { particle: Particle }) {
  if (isParticleDeleted(particle)) {
    return (
      <p className="text-muted-foreground text-xs italic">
        This particle was deleted
      </p>
    );
  }

  switch (particle.type) {
    case 'text':
      return (
        <p className="text-muted-foreground line-clamp-2 whitespace-pre-line text-xs leading-relaxed [overflow-wrap:anywhere]">
          {particle.properties.content}
        </p>
      );
    case 'media': {
      const mime = particle.properties.mime_type;
      const transcript = particle.properties.transcript?.transcript;
      const isVideo = mime.startsWith('video/');
      const isAudio = mime.startsWith('audio/');
      const isImage = mime.startsWith('image/');
      const Icon = isVideo ? Video : isAudio ? Mic : isImage ? Image : Video;
      const label = isVideo
        ? 'Video clip'
        : isAudio
          ? 'Voice note'
          : isImage
            ? 'Photo'
            : 'Media';
      const durationSec = Math.round(particle.properties.duration_ms / 1000);
      const duration =
        durationSec > 0
          ? ` · ${Math.floor(durationSec / 60)}:${String(durationSec % 60).padStart(2, '0')}`
          : '';
      return (
        <div className="flex flex-col gap-0.5">
          <span className="text-muted-foreground flex items-center gap-1.5 text-xs">
            <Icon className="text-muted-foreground size-3.5 shrink-0" />
            {label}
            {duration}
          </span>
          {transcript && (
            <p className="text-muted-foreground line-clamp-2 text-xs leading-relaxed">
              {transcript}
            </p>
          )}
        </div>
      );
    }
    case 'file':
      return (
        <span className="text-muted-foreground flex items-center gap-1.5 text-xs">
          <FileText className="text-muted-foreground size-3.5 shrink-0" />
          <span className="truncate">{particle.properties.filename}</span>
        </span>
      );
    case 'task': {
      const { title, done, checklist = [] } = particle.properties;
      const doneCount = checklist.filter((item) => item.done).length;
      return (
        <div className="flex flex-col gap-0.5">
          <span className="text-muted-foreground flex items-center gap-1.5 text-xs">
            <CircleCheck
              className={cn(
                'size-3.5 shrink-0',
                done
                  ? 'text-emerald-600 dark:text-emerald-400'
                  : 'text-muted-foreground',
              )}
            />
            <span
              className={cn(
                'truncate',
                done && 'text-muted-foreground line-through',
              )}
            >
              {title}
            </span>
          </span>
          {checklist.length > 0 && (
            <span className="text-muted-foreground pl-5 text-[10px]">
              {doneCount} / {checklist.length} subtasks
            </span>
          )}
        </div>
      );
    }
    case 'paper':
      return (
        <p className="text-muted-foreground truncate text-xs">
          {particle.properties.title}
        </p>
      );
    default:
      return <p className="text-muted-foreground text-xs">{particle.type}</p>;
  }
}
