// Read-only queue sheet for the Desktop Remote: the desktop's current +
// upcoming tracks, tap-to-play. Deliberately NOT the native queue — that reads
// the local playback session straight out of Room (drag-reorder, swipe-remove,
// multi-select), none of which applies to a remote snapshot. This is the only
// remaining React Native queue surface. It uses an INLINE BottomSheet because
// BottomSheetModal's portal does not work in this app's screen setups (see
// queue-tray-sheet gotcha).

import { useCallback, useEffect, useMemo } from 'react';
import { Pressable, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import BottomSheet, {
  BottomSheetBackdrop,
  type BottomSheetBackdropProps,
  type BottomSheetHandleProps,
  useBottomSheetScrollableCreator,
} from '@gorhom/bottom-sheet';
import { FlashList, type ListRenderItemInfo } from '@shopify/flash-list';
import { Text } from '@/components/Text';
import { radius, spacing } from '@/theme';
import { createThemedStyles, useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { formatDuration } from '@/lib/format';
import { useDesktopRemoteStore } from '@/stores/desktopRemoteStore';
import type { DesktopRemoteQueueItem } from '@/types/desktopRemote';
import { QueueSheetHandle } from './QueueSheetHandle';

interface RemoteQueueSheetProps {
  onClose: () => void;
  embedded?: boolean;
}

export function RemoteQueueSheet({ onClose, embedded = false }: RemoteQueueSheetProps) {
  const styles = useStyles();
  const colors = useColors();
  const ripple = useRipple();
  const queue = useDesktopRemoteStore((s) => s.queue);
  const snapPoints = useMemo(() => ['58%', '100%'], []);
  const renderFlashListScrollComponent = useBottomSheetScrollableCreator();

  // The SSE stream keeps the queue fresh while connected; refresh once on open
  // in case the stream fell back to snapshot polling (which has no queue).
  useEffect(() => {
    void useDesktopRemoteStore.getState().refreshQueue();
  }, []);

  const items = queue?.items ?? [];
  const upcomingCount = items.filter((item) => !item.isCurrent).length;

  const renderBackdrop = useCallback(
    (props: BottomSheetBackdropProps) => (
      <BottomSheetBackdrop
        {...props}
        appearsOnIndex={0}
        disappearsOnIndex={-1}
        pressBehavior="close"
        opacity={0.58}
      />
    ),
    []
  );

  const playItem = useCallback(
    (item: DesktopRemoteQueueItem) => {
      if (item.isCurrent) return;
      void useDesktopRemoteStore.getState().playQueueItem(item.queueId);
      onClose();
    },
    [onClose]
  );

  const renderItem = useCallback(
    ({ item }: ListRenderItemInfo<DesktopRemoteQueueItem>) => (
      <Pressable
        android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY}
        style={styles.row}
        onPress={() => playItem(item)}
        disabled={item.isCurrent}
        accessibilityRole="button"
        accessibilityLabel={
          item.isCurrent ? `Now playing: ${item.title}` : `Play ${item.title} on desktop`
        }
      >
        <View style={styles.rowText}>
          <Text
            variant="body"
            numberOfLines={1}
            style={item.isCurrent ? styles.titleActive : undefined}
          >
            {item.title || 'Unknown title'}
          </Text>
          <Text variant="label" numberOfLines={1} color={colors.textTertiary}>
            {item.artist || 'Unknown artist'}
          </Text>
        </View>
        {item.isCurrent ? (
          <Ionicons name="volume-high" size={18} color={colors.accent} />
        ) : item.durationSeconds !== null ? (
          <Text variant="label" color={colors.textTertiary}>
            {formatDuration(item.durationSeconds)}
          </Text>
        ) : null}
      </Pressable>
    ),
    [playItem, colors, styles, ripple]
  );

  const topSection = useMemo(
    () => (
      <View style={styles.headerRow}>
        <Text variant="heading">Desktop queue</Text>
        <Text variant="label" color={colors.textTertiary}>
          {upcomingCount === 1 ? '1 song up next' : `${upcomingCount} songs up next`}
        </Text>
      </View>
    ),
    [colors.textTertiary, styles.headerRow, upcomingCount]
  );

  const content = (
    <FlashList
      data={items}
      keyExtractor={(item) => item.queueId}
      renderScrollComponent={embedded ? undefined : renderFlashListScrollComponent}
      renderItem={renderItem}
      contentContainerStyle={styles.listContent}
      showsVerticalScrollIndicator={false}
      ListEmptyComponent={
        <View style={styles.empty}>
          <Text variant="body" color={colors.textSecondary}>
            The desktop queue is empty.
          </Text>
        </View>
      }
    />
  );

  const renderSheetHandle = useCallback(
    (props: BottomSheetHandleProps) => (
      <QueueSheetHandle {...props}>
        {topSection}
      </QueueSheetHandle>
    ),
    [topSection]
  );

  if (embedded) {
    return (
      <View style={styles.embeddedRoot}>
        {topSection}
        {content}
      </View>
    );
  }

  return (
    <BottomSheet
      index={0}
      snapPoints={snapPoints}
      enableDynamicSizing={false}
      enablePanDownToClose
      onClose={onClose}
      backdropComponent={renderBackdrop}
      backgroundStyle={styles.sheetBg}
      handleComponent={renderSheetHandle}
      handleIndicatorStyle={styles.handle}
    >
      {content}
    </BottomSheet>
  );
}

const useStyles = createThemedStyles((colors) => ({
  sheetBg: {
    backgroundColor: colors.bgSecondary,
    borderRadius: radius.lg,
  },
  handle: {
    backgroundColor: colors.textTertiary,
  },
  embeddedRoot: {
    flex: 1,
    overflow: 'hidden',
  },
  headerRow: {
    flexDirection: 'row',
    alignItems: 'baseline',
    justifyContent: 'space-between',
    paddingHorizontal: spacing.lg,
    paddingBottom: spacing.sm,
  },
  listContent: {
    paddingHorizontal: spacing.lg,
    paddingBottom: spacing.xl,
  },
  row: {
    minHeight: 56,
    flexDirection: 'row',
    alignItems: 'center',
    gap: spacing.md,
  },
  rowText: {
    flex: 1,
    minWidth: 0,
  },
  titleActive: {
    color: colors.accent,
  },
  empty: {
    paddingVertical: spacing.xl,
    alignItems: 'center',
  },
}));
