import { useEffect, useRef, useState } from "react";
import type { MediaParticleData, StreamParticle } from "@/api/types";
import { apiClient } from "@/api/client";
import { usePlaybackStore } from "@/stores/playback-store";
import { Skeleton } from "@/components/ui/skeleton";
import { AudioLevelBars } from "@/components/audio/audio-level-bars";
import { useAudioSource } from "@/components/audio/use-audio-source";

interface MediaParticleViewProps {
  particle: StreamParticle;
  onEnded: () => void;
}

function formatTime(ms: number): string {
  const totalSeconds = Math.floor(ms / 1000);
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;
  return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}

function DurationPill({
  currentTimeMs,
  totalDurationMs,
}: {
  currentTimeMs: number;
  totalDurationMs: number;
}) {
  return (
    <div className="absolute top-3 right-3 rounded-full bg-white/10 px-2.5 py-1 backdrop-blur-sm">
      <span className="font-mono text-xs text-white/80">
        {formatTime(currentTimeMs)} / {formatTime(totalDurationMs)}
      </span>
    </div>
  );
}

export function MediaParticleView({
  particle,
  onEnded,
}: MediaParticleViewProps) {
  const cachedUrl = usePlaybackStore(
    (s) => s.downloadUrlCache[particle.id],
  );
  const cacheDownloadUrl = usePlaybackStore((s) => s.cacheDownloadUrl);
  const paused = usePlaybackStore((s) => s.paused);
  const [error, setError] = useState<string | null>(null);

  const videoRef = useRef<HTMLVideoElement>(null);
  const audioRef = useRef<HTMLAudioElement>(null);
  const [currentTimeMs, setCurrentTimeMs] = useState(0);

  const data = particle.data as MediaParticleData;
  const isAudio = data.mime_type?.startsWith("audio/");

  useEffect(() => {
    if (cachedUrl) {
      return;
    }

    let cancelled = false;
    apiClient
      .getParticleDownloadUrl(particle.id)
      .then((downloadUrl) => {
        if (cancelled) return;
        cacheDownloadUrl(particle.id, downloadUrl);
      })
      .catch(() => {
        if (!cancelled) setError("Failed to load media");
      });

    return () => {
      cancelled = true;
    };
  }, [particle.id, cacheDownloadUrl]);

  // Handle pause/resume
  useEffect(() => {
    var el: HTMLVideoElement | HTMLAudioElement | null = null;
    if (isAudio) {
      el = audioRef.current;
    } else {
      el = videoRef.current;
    }

    if (!el) return;

    if (paused) {
      el.pause();
    } else {
      el.play().catch(() => {
        console.warn("Playback failed", { particleId: particle.id });
      });
    }
  }, [paused]);

  if (error) {
    return (
      <div className="text-muted-foreground flex items-center justify-center text-sm">
        {error}
      </div>
    );
  }

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

  if (isAudio) {
    return (
      <div className="relative flex h-full w-full items-center justify-center bg-black/90">
        <audio
          ref={audioRef}
          crossOrigin="anonymous"
          src={cachedUrl}
          autoPlay
          onEnded={onEnded}
          onTimeUpdate={(e) => {
            setCurrentTimeMs(e.currentTarget.currentTime * 1000);
          }}
        />

        <DurationPill
          currentTimeMs={currentTimeMs}
          totalDurationMs={data.duration_ms}
        />
      </div>
    );
  }

  return (
    <div className="relative h-full w-full">
      <video
        ref={videoRef}
        src={cachedUrl}
        autoPlay
        playsInline
        onEnded={onEnded}
        onTimeUpdate={(e) => {
          setCurrentTimeMs(e.currentTarget.currentTime * 1000);
        }}
        className="h-full w-full object-cover"
      />
      <DurationPill
        currentTimeMs={currentTimeMs}
        totalDurationMs={data.duration_ms}
      />
    </div>
  );
}
