import { useMemo, useState } from "react";
import {
  KeyboardAvoidingView,
  Platform,
  Pressable,
  Text,
  TextInput,
  View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { StatusBar } from "expo-status-bar";
import { ChevronRight, Globe, Lock, X } from "lucide-react-native";
import { toast } from "sonner-native";
import { ComposeDock } from "@/features/compose/ComposeDock";
import { useNetwork } from "@/hooks/use-networks";
import { particlePath } from "@/lib/particle-path";
import { generateRandomName } from "@/lib/random-name";
import { createStreamWithFirstParticle } from "@/lib/upload";
import { toUserMessage } from "@/lib/errors";
import {
  buildNetworkVisibility,
  parseVisibleTo,
} from "@/lib/stream-visibility";
import { useAuthStore } from "@/stores/auth-store";
import type { RootStackScreenProps } from "@/navigation/types";
import { VisibilityPickerSheet } from "./VisibilityPickerSheet";

const STREAM_NAME_MAX = 60;

/**
 * Top-level stream creation. The user names the stream, picks visibility, and
 * composes the first particle on one screen — desktop's compose-overlay flow
 * collapsed into a touch-native single page.
 */
export function NewStreamScreen({
  route,
  navigation,
}: RootStackScreenProps<"NewStream">) {
  const { networkId } = route.params;
  const network = useNetwork(networkId);
  const userId = useAuthStore((s) => s.user?.id);

  const suggestion = useMemo(() => generateRandomName(), []);
  const [name, setName] = useState("");
  const [visibleTo, setVisibleTo] = useState<string[]>(() =>
    buildNetworkVisibility(networkId),
  );
  const [pickerOpen, setPickerOpen] = useState(false);

  const effectiveName = name.trim() || suggestion;

  const handleStreamCreated = (streamId: string) => {
    navigation.replace("StreamView", { networkId, streamId });
  };

  const submitText = async (content: string) => {
    if (!userId) throw new Error("Not signed in.");
    try {
      const { streamId } = await createStreamWithFirstParticle({
        networkId,
        name: effectiveName,
        visibleTo,
        createdByHumanId: userId,
        firstParticle: { type: "text", content },
      });
      handleStreamCreated(streamId);
    } catch (err) {
      toast.error(toUserMessage(err));
      throw err;
    }
  };

  const submitMedia = async ({
    fileUri,
    mimeType,
    durationMs,
    source,
  }: {
    fileUri: string;
    mimeType: string;
    durationMs: number;
    source: "camera" | "screen";
  }) => {
    if (!userId) throw new Error("Not signed in.");
    try {
      const { streamId } = await createStreamWithFirstParticle({
        networkId,
        name: effectiveName,
        visibleTo,
        createdByHumanId: userId,
        firstParticle: {
          type: "media",
          fileUri,
          mimeType,
          durationMs,
          source,
        },
      });
      handleStreamCreated(streamId);
    } catch (err) {
      toast.error(toUserMessage(err));
      throw err;
    }
  };

  const placeholderPath = particlePath(networkId, []);

  const visibility = parseVisibleTo(visibleTo, networkId);
  const visibleSummary =
    visibility.mode === "network"
      ? `Everyone in ${network?.name ?? "this network"}`
      : `${visibility.humanIds.length} ${
          visibility.humanIds.length === 1 ? "person" : "people"
        }`;

  return (
    <View className="flex-1 bg-black">
      <StatusBar style="light" />

      <SafeAreaView edges={["top"]}>
        <View className="flex-row items-center justify-between px-4 pt-3 pb-2">
          <Pressable
            onPress={() => navigation.goBack()}
            hitSlop={12}
            accessibilityLabel="Cancel"
          >
            <X color="white" size={22} strokeWidth={1.8} />
          </Pressable>
          <Text className="text-white text-base font-semibold">
            New stream
          </Text>
          <View style={{ width: 22 }} />
        </View>
      </SafeAreaView>

      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : undefined}
        className="flex-1"
      >
        <View className="flex-1 px-6 pt-4">
          <Text className="text-white/60 text-xs uppercase tracking-wide mb-2">
            Name
          </Text>
          <TextInput
            value={name}
            onChangeText={(v) => setName(v.slice(0, STREAM_NAME_MAX))}
            placeholder={suggestion}
            placeholderTextColor="rgba(255,255,255,0.35)"
            autoCapitalize="none"
            autoCorrect={false}
            maxLength={STREAM_NAME_MAX}
            className="bg-white/10 rounded-xl px-4 py-3 text-white text-lg"
          />

          <Text className="text-white/60 text-xs uppercase tracking-wide mt-6 mb-2">
            Visible to
          </Text>
          <Pressable
            onPress={() => setPickerOpen(true)}
            className="bg-white/10 active:bg-white/15 rounded-xl px-4 py-3 flex-row items-center gap-3"
          >
            {visibility.mode === "network" ? (
              <Globe color="rgba(255,255,255,0.7)" size={18} strokeWidth={1.6} />
            ) : (
              <Lock color="rgba(255,255,255,0.7)" size={18} strokeWidth={1.6} />
            )}
            <Text className="text-white text-base flex-1" numberOfLines={1}>
              {visibleSummary}
            </Text>
            <ChevronRight
              color="rgba(255,255,255,0.5)"
              size={18}
              strokeWidth={1.6}
            />
          </Pressable>

          <View className="mt-6 px-1">
            <Text className="text-white/50 text-sm">
              Hold the button below to record a voice or video message — that's
              the first particle in your new stream.
            </Text>
          </View>
        </View>
      </KeyboardAvoidingView>

      <ComposeDock
        networkId={networkId}
        targetPath={placeholderPath}
        silentPresence
        submitMedia={submitMedia}
        submitText={submitText}
      />

      <VisibilityPickerSheet
        open={pickerOpen}
        onClose={() => setPickerOpen(false)}
        networkId={networkId}
        networkName={network?.name}
        humans={network?.humans ?? []}
        selfHumanId={userId}
        visibleTo={visibleTo}
        onChange={setVisibleTo}
      />
    </View>
  );
}
