import { useMemo } from 'react';
import { Pressable, ScrollView, Text, View } from 'react-native';
import { Globe, Lock, X } from 'lucide-react-native';
import { toast } from 'sonner-native';
import type { Particle } from '@/api/types';
import { resolveHumanDisplay } from '@/lib/humans';
import { useNetwork } from '@/hooks/use-networks';
import { particlePath, toFirestoreDocPath } from '@/lib/particle-path';
import { updateParticleVisibleTo } from '@/lib/firestore-particles';
import {
  buildCustomVisibility,
  buildNetworkVisibility,
  parseVisibleTo,
} from '@/lib/stream-visibility';
import { toUserMessage } from '@/lib/errors';
import { useSuspendPlayback } from '@/hooks/use-suspend-playback';
import { BottomSheet } from '@/components/BottomSheet';
import { Avatar } from '@/components/Avatar';
import { useStreamPresence } from './stream-presence-context';

interface StreamMembersSheetProps {
  open: boolean;
  onClose: () => void;
  networkId: string;
  streamParticle: Particle & { type: 'stream' };
  isCreator: boolean;
}

/**
 * Read-only-for-non-creators view of who can see the stream, plus an inline
 * editor for creators to flip between network-wide and per-person and to
 * add/remove people. Mobile counterpart of stream-members-overlay.tsx.
 */
export function StreamMembersSheet({
  open,
  onClose,
  networkId,
  streamParticle,
  isCreator,
}: StreamMembersSheetProps) {
  useSuspendPlayback(open, 'stream-members');

  const { onlineHumanIds } = useStreamPresence();
  const network = useNetwork(networkId);
  const humans = network?.humans ?? [];
  const creatorId = streamParticle.created_by_human_id;
  const visibility = parseVisibleTo(streamParticle.visible_to, networkId);

  const docPath = useMemo(
    () => toFirestoreDocPath(particlePath(networkId, [streamParticle.id])),
    [networkId, streamParticle.id],
  );

  const memberIds =
    visibility.mode === 'network'
      ? humans.map((h) => h.id)
      : visibility.humanIds;
  const memberSet = new Set(memberIds);
  const availableToAdd = humans.filter((h) => !memberSet.has(h.id));

  const apply = async (next: string[]) => {
    try {
      await updateParticleVisibleTo(docPath, next);
    } catch (err) {
      toast.error(toUserMessage(err));
    }
  };

  const setNetworkWide = () => apply(buildNetworkVisibility(networkId));
  const setCustomOnlyCreator = () => apply(buildCustomVisibility([creatorId]));

  const removeMember = (id: string) => {
    if (visibility.mode !== 'custom') return;
    if (id === creatorId) return;
    const next = visibility.humanIds.filter((x) => x !== id);
    if (next.length === 0) return;
    void apply(buildCustomVisibility(next));
  };

  const addMember = (id: string) => {
    if (visibility.mode !== 'custom') return;
    void apply(buildCustomVisibility([...visibility.humanIds, id]));
  };

  return (
    <BottomSheet open={open} onClose={onClose} maxHeight="85%">
      <View className="flex-row items-center justify-between px-5 pb-3">
        <View style={{ width: 22 }} />
        <Text className="text-white text-base font-semibold">Members</Text>
        <Pressable onPress={onClose} hitSlop={12}>
          <X color="rgba(255,255,255,0.7)" size={22} />
        </Pressable>
      </View>

      <View className="px-5 pb-3">
        <Text className="text-white/40 text-[10px] font-semibold uppercase tracking-widest mb-2">
          Visibility
        </Text>
        {isCreator ? (
          <View className="flex-row gap-1 bg-white/5 rounded-lg p-1">
            <ModePill
              active={visibility.mode === 'network'}
              icon={<Globe color="white" size={14} />}
              label="Network-wide"
              onPress={setNetworkWide}
            />
            <ModePill
              active={visibility.mode === 'custom'}
              icon={<Lock color="white" size={14} />}
              label="Specific people"
              onPress={setCustomOnlyCreator}
            />
          </View>
        ) : (
          <View className="flex-row items-center gap-2">
            {visibility.mode === 'network' ? (
              <>
                <Globe color="rgba(255,255,255,0.5)" size={14} />
                <Text className="text-white/70 text-sm">
                  Everyone in {network?.name ?? 'network'}
                </Text>
              </>
            ) : (
              <>
                <Lock color="rgba(255,255,255,0.5)" size={14} />
                <Text className="text-white/70 text-sm">
                  {memberIds.length} specific{' '}
                  {memberIds.length === 1 ? 'person' : 'people'}
                </Text>
              </>
            )}
          </View>
        )}
      </View>

      <ScrollView contentContainerClassName="pb-4">
        <View className="px-5 pt-2">
          <Text className="text-white/40 text-[10px] font-semibold uppercase tracking-widest mb-2">
            {visibility.mode === 'network' ? 'Has access' : 'People'} ·{' '}
            {memberIds.length}
          </Text>
          {memberIds.map((id) => {
            const display = resolveHumanDisplay(id, humans);
            const isCreatorRow = id === creatorId;
            const canRemove =
              isCreator && visibility.mode === 'custom' && !isCreatorRow;
            return (
              <View key={id} className="flex-row items-center gap-3 py-2.5">
                <Avatar
                  humanId={id}
                  humans={humans}
                  size="sm"
                  online={onlineHumanIds.has(id)}
                />
                <View className="flex-1">
                  <Text
                    className={
                      display.exists
                        ? 'text-white text-sm font-medium'
                        : 'text-white/50 italic text-sm font-medium'
                    }
                    numberOfLines={1}
                  >
                    {display.displayName}
                  </Text>
                  {display.exists ? (
                    <Text className="text-white/40 text-xs" numberOfLines={1}>
                      {display.email}
                    </Text>
                  ) : null}
                </View>
                {isCreatorRow ? (
                  <Text className="text-white/30 text-[10px] uppercase tracking-wider">
                    Creator
                  </Text>
                ) : canRemove ? (
                  <Pressable
                    onPress={() => removeMember(id)}
                    hitSlop={10}
                    accessibilityLabel={`Remove ${display.displayName}`}
                  >
                    <X color="rgba(255,255,255,0.6)" size={18} />
                  </Pressable>
                ) : null}
              </View>
            );
          })}
        </View>

        {isCreator &&
        visibility.mode === 'custom' &&
        availableToAdd.length > 0 ? (
          <View className="px-5 pt-4 mt-2 border-t border-white/5">
            <Text className="text-white/40 text-[10px] font-semibold uppercase tracking-widest mt-3 mb-2">
              Add people
            </Text>
            {availableToAdd.map((human) => {
              const display = resolveHumanDisplay(human.id, humans);
              return (
                <Pressable
                  key={human.id}
                  onPress={() => addMember(human.id)}
                  className="flex-row items-center gap-3 py-2.5 active:bg-white/5 rounded-lg"
                >
                  <Avatar
                    humanId={human.id}
                    humans={humans}
                    size="sm"
                    online={onlineHumanIds.has(human.id)}
                  />
                  <View className="flex-1">
                    <Text
                      className="text-white text-sm font-medium"
                      numberOfLines={1}
                    >
                      {display.displayName}
                    </Text>
                    <Text className="text-white/40 text-xs" numberOfLines={1}>
                      {display.email}
                    </Text>
                  </View>
                  <Text className="text-white/60 text-sm">Add</Text>
                </Pressable>
              );
            })}
          </View>
        ) : null}
      </ScrollView>
    </BottomSheet>
  );
}

function ModePill({
  active,
  icon,
  label,
  onPress,
}: {
  active: boolean;
  icon: React.ReactNode;
  label: string;
  onPress: () => void;
}) {
  return (
    <Pressable
      onPress={onPress}
      className={
        'flex-1 flex-row items-center justify-center gap-1.5 rounded-md py-2 ' +
        (active ? 'bg-white/15' : '')
      }
    >
      {icon}
      <Text
        className={
          active ? 'text-white text-xs font-semibold' : 'text-white/60 text-xs'
        }
      >
        {label}
      </Text>
    </Pressable>
  );
}
