import { useEffect, useRef } from "react";
import type { StreamParticle } from "@/api/types";
import { apiClient } from "@/api/client";
import { useAppStore } from "@/stores/app-store";
import { usePlaybackStore } from "@/stores/playback-store";
import { MediaParticleView } from "./media-particle-view";
import { TextParticleView } from "./text-particle-view";
import { FallbackParticleView } from "./fallback-particle-view";
import { AckButton } from "./ack-button";

interface ParticleRendererProps {
  particle: StreamParticle;
}

export function ParticleRenderer({
  particle,
}: ParticleRendererProps) {
  const next = usePlaybackStore((s) => s.next);
  const prev = usePlaybackStore((s) => s.prev);

  const markParticlesSeen = useAppStore((s) => s.markParticlesSeen);
  const markedRef = useRef<string | null>(null);

  useEffect(() => {
    if (!particle.seen && markedRef.current !== particle.id) {
      markedRef.current = particle.id;
      markParticlesSeen([particle.id]);
      apiClient.markSeen(particle.id);
    }
  }, [particle.id, particle.seen, markParticlesSeen]);

  const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = (e.clientX - rect.left) / rect.width;
    if (x < 0.3) prev();
    else if (x > 0.7) next();
  };

  const renderContent = () => {
    switch (particle.type) {
      case "media":
        {/* NOTE: it's more robust to re-mount the MediaParticleView when the particle changes, to ensure playback state is well-behaved */ }
        return <MediaParticleView key={particle.id} particle={particle} />;
      case "text":
        return <TextParticleView particle={particle} />;
      default:
        return <FallbackParticleView particle={particle} />;
    }
  };

  return (
    <div
      className="relative flex h-full w-full cursor-pointer items-center justify-center"
      onClick={handleClick}
    >
      {renderContent()}
      <div className="absolute right-4 bottom-16">
        <AckButton particleId={particle.id} acks={particle.acks} />
      </div>
    </div>
  );
}

function RenderParticle({ particle }: { particle: StreamParticle }) {
  switch (particle.type) {
    case "media":
      return <MediaParticleView particle={particle} />;
    case "text":
      return <TextParticleView particle={particle} />;
    default:
      return <FallbackParticleView particle={particle} />;
  }
}
