import { useEffect, useState } from 'react';
import type { Particle } from '@/api/types';
import { apiClient } from '@/api/client';
import { Skeleton } from '@/components/ui/skeleton';
import {
  Video,
  Mic,
  CircleCheck,
  CalendarDays,
  BookOpen,
  FileIcon,
  FolderIcon,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { formatEventTime } from '@/lib/particle-display';

export function ParticlePreview({ particle }: { particle: Particle }) {
  switch (particle.type) {
    case 'text':
      return <TextPreview particle={particle} />;
    case 'media':
      return <MediaPreview particle={particle} />;
    case 'task':
      return <TaskPreview particle={particle} />;
    case 'event':
      return <EventPreview particle={particle} />;
    case 'paper':
      return <PaperPreview particle={particle} />;
    case 'file':
      return <FilePreview particle={particle} />;
    case 'folder':
      return <FolderPreview particle={particle} />;
    default:
      return <EmptyPreview />;
  }
}

function TextPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'text' }>;
}) {
  const truncated =
    particle.properties.content.length > 30
      ? particle.properties.content.slice(0, 30) + '...'
      : particle.properties.content;
  return (
    <div className="flex h-full w-full items-center justify-center p-4">
      <p className="line-clamp-4 text-center text-xl leading-relaxed">
        {truncated}
      </p>
    </div>
  );
}

function MediaPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'media' }>;
}) {
  const { mime_type, duration_ms } = particle.properties;
  const isVideo = mime_type.startsWith('video');
  const durationSec = Math.round(duration_ms / 1000);
  const durationLabel = `${Math.floor(durationSec / 60)}:${String(durationSec % 60).padStart(2, '0')}`;

  if (isVideo) {
    return (
      <VideoThumbnail
        particleId={particle.properties.object_id}
        duration={durationLabel}
      />
    );
  }

  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-black/90">
      <Mic className="h-8 w-8 text-white/60" />
      <span className="font-mono text-xs text-white/50">{durationLabel}</span>
    </div>
  );
}

function VideoThumbnail({
  particleId,
  duration,
}: {
  particleId: string;
  duration: string;
}) {
  const [url, setUrl] = useState<string | null>(null);
  const [error, setError] = useState(false);

  useEffect(() => {
    let cancelled = false;
    apiClient
      .getParticleDownloadUrl(particleId)
      .then((downloadUrl) => {
        if (!cancelled) setUrl(downloadUrl);
      })
      .catch(() => {
        if (!cancelled) setError(true);
      });
    return () => {
      cancelled = true;
    };
  }, [particleId]);

  if (error) {
    return (
      <div className="flex h-full w-full items-center justify-center bg-black/80">
        <Video className="h-8 w-8 text-white/40" />
      </div>
    );
  }

  if (!url) {
    return <Skeleton className="h-full w-full rounded-none" />;
  }

  return (
    <div className="relative h-full w-full bg-black">
      <video
        src={`${url}#t=2`}
        preload="metadata"
        muted
        playsInline
        className="h-full w-full object-cover"
      />
      <span className="absolute right-1.5 bottom-1.5 rounded bg-black/70 px-1.5 py-0.5 font-mono text-[10px] text-white/80">
        {duration}
      </span>
    </div>
  );
}

function TaskPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'task' }>;
}) {
  const { title, done } = particle.properties;
  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-amber-500/10 p-4">
      <CircleCheck
        className={cn(
          'h-6 w-6',
          done
            ? 'text-emerald-600/80 dark:text-emerald-400/80'
            : 'text-amber-600/70 dark:text-amber-400/70',
        )}
      />
      <p
        className={cn(
          'line-clamp-2 text-center text-sm font-medium',
          done && 'text-muted-foreground line-through',
        )}
      >
        {title}
      </p>
    </div>
  );
}

function EventPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'event' }>;
}) {
  const { title, start_at, end_at } = particle.properties;
  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-violet-500/10 p-4">
      <CalendarDays className="h-6 w-6 text-violet-600/70 dark:text-violet-400/70" />
      <p className="line-clamp-2 text-center text-sm font-medium">{title}</p>
      <span className="text-muted-foreground text-center text-[10px]">
        {formatEventTime(start_at, end_at)}
      </span>
    </div>
  );
}

function PaperPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'paper' }>;
}) {
  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-blue-500/10 p-4">
      <BookOpen className="h-6 w-6 text-blue-600/70 dark:text-blue-400/70" />
      <p className="line-clamp-2 text-center text-sm font-medium">
        {particle.properties.title}
      </p>
    </div>
  );
}

function FilePreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'file' }>;
}) {
  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-emerald-500/10 p-4">
      <FileIcon className="h-6 w-6 text-emerald-600/70 dark:text-emerald-400/70" />
      <p className="text-muted-foreground line-clamp-1 text-center text-xs">
        {particle.properties.filename}
      </p>
    </div>
  );
}

function FolderPreview({
  particle,
}: {
  particle: Extract<Particle, { type: 'folder' }>;
}) {
  return (
    <div className="flex h-full w-full flex-col items-center justify-center gap-2 bg-orange-500/10 p-4">
      <FolderIcon className="h-6 w-6 text-orange-600/70 dark:text-orange-400/70" />
      <p className="text-muted-foreground line-clamp-1 text-center text-xs">
        {particle.properties.name}
      </p>
    </div>
  );
}

function EmptyPreview() {
  return (
    <div className="flex h-full w-full items-center justify-center">
      <p className="text-muted-foreground text-xs italic">No messages yet</p>
    </div>
  );
}
