import React, { useEffect, useRef, type ReactNode } from 'react';
import { Animated, Pressable, ScrollView, Text, View, type StyleProp, type ViewStyle } from 'react-native';
import { RefreshCw, Sparkles, X } from 'lucide-react-native';

import { composerSuggestionStyles as s } from './composerSuggestionStyles';
import { ConnectorBrandIcon, hasConnectorBrandIcon } from '../connectors/connectorBrandIcons';
import { styles } from '../../styles';
import { themedColor } from '../../theme';
import type { SuperagentPromptSuggestion } from '../../types';

const ICON_COLOR = '#A1A1AA';
const SKELETON_WIDTHS = [110, 140, 120];

/**
 * Prompt-suggestion chips shown above the composer input — the native mirror of the web
 * builder's `ChatInputSuggestionsAbove` in its new design-system variant (DS `Chip
 * skin="light"` + ghost `IconButton`s, sparkles restore). Pure UI: the parent
 * (`ConversationChat`) owns the suggestion state, fills the draft on select, and reports
 * analytics. Renders the chip row when `visible`, a collapsed restore button when
 * `showRestore`, and nothing otherwise.
 *
 * Native intentionally omits two desktop-only web affordances — auto-shortening chip titles
 * to fit the row, and the hover-to-preview placeholder — matching the web builder's own
 * mobile behavior (both are gated off on touch widths there).
 */
export function ComposerSuggestions({
  suggestions,
  visible,
  showRestore,
  refreshing,
  onSelect,
  onRefresh,
  onDismiss,
  onRestore,
}: {
  suggestions: SuperagentPromptSuggestion[];
  visible: boolean;
  showRestore: boolean;
  refreshing: boolean;
  onSelect: (suggestion: SuperagentPromptSuggestion) => void;
  onRefresh: () => void;
  onDismiss: () => void;
  onRestore: () => void;
}) {
  if (visible) {
    return (
      <FadeIn style={s.row}>
        <ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          keyboardShouldPersistTaps="handled"
          contentContainerStyle={s.scrollContent}
          style={s.scroll}
        >
          {refreshing
            ? SKELETON_WIDTHS.map((width, index) => <SkeletonChip key={index} width={width} />)
            : suggestions.map((suggestion, index) => (
                <SuggestionChip key={`${suggestion.title}-${index}`} suggestion={suggestion} onSelect={onSelect} />
              ))}
        </ScrollView>
        <View style={s.actions}>
          <ActionButton accessibilityLabel="Refresh suggestions" disabled={refreshing} onPress={onRefresh}>
            <RefreshCw color={themedColor(ICON_COLOR)} size={16} strokeWidth={2} />
          </ActionButton>
          <ActionButton accessibilityLabel="Hide suggestions" onPress={onDismiss}>
            <X color={themedColor(ICON_COLOR)} size={16} strokeWidth={2} />
          </ActionButton>
        </View>
      </FadeIn>
    );
  }

  if (showRestore) {
    return (
      <FadeIn style={s.restoreRow}>
        <ActionButton accessibilityLabel="Show suggestions" boxed onPress={onRestore}>
          <Sparkles color={themedColor(ICON_COLOR)} size={16} strokeWidth={2} />
        </ActionButton>
      </FadeIn>
    );
  }

  return null;
}

function SuggestionChip({
  suggestion,
  onSelect,
}: {
  suggestion: SuperagentPromptSuggestion;
  onSelect: (suggestion: SuperagentPromptSuggestion) => void;
}) {
  const connectorTypes = Array.from(new Set(suggestion.connector_types ?? [])).filter(hasConnectorBrandIcon);
  return (
    <Pressable
      accessibilityRole="button"
      accessibilityLabel={suggestion.title}
      onPress={() => onSelect(suggestion)}
      style={({ pressed }) => [s.chip, pressed && styles.pressed]}
    >
      {connectorTypes.map((type) => (
        <View key={type} style={s.chipIcon}>
          <ConnectorBrandIcon connectorId={type} size={18} />
        </View>
      ))}
      <Text numberOfLines={1} style={s.chipText}>
        {suggestion.title}
      </Text>
    </Pressable>
  );
}

function SkeletonChip({ width }: { width: number }) {
  const opacity = useRef(new Animated.Value(0.4)).current;
  useEffect(() => {
    const loop = Animated.loop(
      Animated.sequence([
        Animated.timing(opacity, { toValue: 0.85, duration: 600, useNativeDriver: true }),
        Animated.timing(opacity, { toValue: 0.4, duration: 600, useNativeDriver: true }),
      ]),
    );
    loop.start();
    return () => loop.stop();
  }, [opacity]);
  return <Animated.View style={[s.skeleton, { width, opacity }]} />;
}

function ActionButton({
  accessibilityLabel,
  boxed,
  children,
  disabled,
  onPress,
}: {
  accessibilityLabel: string;
  /** Bordered-box style (the restore affordance); refresh/dismiss default to the ghost look. */
  boxed?: boolean;
  children: ReactNode;
  disabled?: boolean;
  onPress: () => void;
}) {
  return (
    <Pressable
      accessibilityRole="button"
      accessibilityLabel={accessibilityLabel}
      disabled={disabled}
      onPress={onPress}
      style={({ pressed }) => [
        boxed ? s.restoreButton : s.actionButton,
        disabled && s.actionButtonDisabled,
        pressed && styles.pressed,
      ]}
    >
      {children}
    </Pressable>
  );
}

function FadeIn({ children, style }: { children: ReactNode; style?: StyleProp<ViewStyle> }) {
  const opacity = useRef(new Animated.Value(0)).current;
  useEffect(() => {
    Animated.timing(opacity, { toValue: 1, duration: 200, useNativeDriver: true }).start();
  }, [opacity]);
  return <Animated.View style={[style, { opacity }]}>{children}</Animated.View>;
}
