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
        allowTask={false}
        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>
  );
}
