import { useEffect } from "react";
import { Text, View } from "react-native";
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withRepeat,
  withTiming,
} from "react-native-reanimated";
import type { Human } from "@/api/types";
import { resolveHumanDisplay } from "@/lib/humans";
import type { ComposingUser } from "@/features/stream-view/stream-presence-context";

interface ComposingIndicatorProps {
  users: ComposingUser[];
  networkHumans?: Human[];
}

/**
 * Slim horizontal pill stack pinned just under the metadata header. Each
 * pill is the typing/recording indicator for a single user. Rendered above
 * the particle canvas with a translucent background so it reads on any
 * media. Mobile equivalent of desktop's vertical writing-mode indicator.
 */
export function ComposingIndicator({
  users,
  networkHumans,
}: ComposingIndicatorProps) {
  if (users.length === 0) return null;

  return (
    <View pointerEvents="none" className="flex-row flex-wrap items-center gap-1.5">
      {users.map((u) => {
        const { displayName } = resolveHumanDisplay(u.humanId, networkHumans);
        const label =
          u.mode === "recording"
            ? `${displayName} is recording`
            : u.mode === "screen"
              ? `${displayName} is sharing`
              : `${displayName} is typing`;

        return (
          <View
            key={u.humanId}
            className="bg-white/15 flex-row items-center gap-1.5 rounded-full px-2 py-1"
          >
            <BouncingDots />
            <Text className="text-white/80 text-[11px] font-medium">
              {label}
            </Text>
          </View>
        );
      })}
    </View>
  );
}

function BouncingDots() {
  return (
    <View className="flex-row items-end gap-0.5" style={{ height: 8 }}>
      <Dot delay={0} />
      <Dot delay={150} />
      <Dot delay={300} />
    </View>
  );
}

function Dot({ delay }: { delay: number }) {
  const y = useSharedValue(0);

  useEffect(() => {
    const start = setTimeout(() => {
      y.value = withRepeat(
        withTiming(-3, {
          duration: 360,
          easing: Easing.inOut(Easing.quad),
        }),
        -1,
        true,
      );
    }, delay);
    return () => clearTimeout(start);
  }, [delay, y]);

  const style = useAnimatedStyle(() => ({
    transform: [{ translateY: y.value }],
  }));

  return (
    <Animated.View
      className="bg-white/85 h-1 w-1 rounded-full"
      style={style}
    />
  );
}
