import { useI18n } from '@/hooks/useI18n';
import type { MedicationDisplayItem } from '@/types/medication';
import React, { useEffect } from 'react';
import { StyleSheet, TouchableOpacity, View } from 'react-native';
import Animated, {
  Extrapolation,
  interpolate,
  type SharedValue,
  useAnimatedStyle,
  useSharedValue,
  withSpring,
} from 'react-native-reanimated';
import { MedicationCard } from './MedicationCard';

type Props = {
  medications: MedicationDisplayItem[];
  colors: (typeof import('@/constants/Colors').Colors)[keyof typeof import('@/constants/Colors').Colors];
  selectedDate: any;
  onOpenDetails: (medication: MedicationDisplayItem) => void;
  onCelebrate?: () => void;
};

const STACK_OFFSET = 12;
const STACK_SCALE_STEP = 0.04;
const MAX_STACK_VISIBLE = 3;

export function TakenMedicationsStack({
  medications,
  colors,
  selectedDate,
  onOpenDetails,
  onCelebrate,
}: Props) {
  const { t } = useI18n();
  const [isExpanded, setIsExpanded] = React.useState(false);
  const progress = useSharedValue(0);

  useEffect(() => {
    progress.value = withSpring(isExpanded ? 1 : 0, {
      damping: 20,
      stiffness: 200, // Faster spring
      mass: 0.8,
    });
  }, [isExpanded, progress]);

  const handleToggle = () => {
    setIsExpanded(!isExpanded);
  };

  // Header arrow rotation style
  const arrowStyle = useAnimatedStyle(() => {
    return {
      transform: [
        {
          rotate: `${interpolate(progress.value, [0, 1], [0, 180])}deg`,
        },
      ],
    };
  });

  if (medications.length === 0) {
    return null;
  }

  return (
    <View style={styles.container}>
      {/* Stack/List Container */}
      <View style={[styles.stackContainer, { minHeight: isExpanded ? undefined : 130 }]}>
        {medications.map((item, index) => (
          <CardItem
            key={item.id || index}
            item={item}
            index={index}
            total={medications.length}
            progress={progress}
            isExpanded={isExpanded}
            colors={colors}
            selectedDate={selectedDate}
            onOpenDetails={onOpenDetails}
            onCelebrate={onCelebrate}
            onToggle={handleToggle}
          />
        ))}
      </View>
    </View>
  );
}

const CardItem = ({
  item,
  index,
  total,
  progress,
  isExpanded,
  colors,
  selectedDate,
  onOpenDetails,
  onCelebrate,
  onToggle,
}: {
  item: MedicationDisplayItem;
  index: number;
  total: number;
  progress: SharedValue<number>;
  isExpanded: boolean;
  colors: (typeof import('@/constants/Colors').Colors)[keyof typeof import('@/constants/Colors').Colors];
  selectedDate: any;
  onOpenDetails: (medication: MedicationDisplayItem) => void;
  onCelebrate?: () => void;
  onToggle: () => void;
}) => {
  // Only render top 3 cards when collapsed to save performance/visuals
  // But we need to render all when expanding.
  // We'll hide index >= MAX_STACK_VISIBLE when collapsed via opacity/zIndex.
  
  const style = useAnimatedStyle(() => {
    // Stack state (progress = 0)
    const stackTranslateY = index * STACK_OFFSET;
    const stackScale = 1 - index * STACK_SCALE_STEP;
    const stackOpacity = index < MAX_STACK_VISIBLE ? 1 - index * 0.15 : 0;
    const stackZIndex = total - index;

    // List state (progress = 1)
    // In list state, we rely on layout (relative positioning).
    // However, to animate smoothly from absolute (stack) to relative (list),
    // we need a strategy.
    // Strategy: Always Absolute? No, height is dynamic.
    // Strategy: Use negative margins for stack?
    
    // Let's try: 
    // Collapsed: marginTop = -(height - offset).
    // Expanded: marginTop = 16 (gap).
    // But we don't know height.
    
    // Alternative:
    // Use 'top' offset relative to the first card?
    // This is hard without measuring.
    
    // Let's go with the "Transform" approach assuming standard card height for the stack effect,
    // but switching to relative layout when expanded.
    // Wait, switching 'position' prop is not animatable by useAnimatedStyle directly (requires Layout Animation).
    
    // Let's keep it simple:
    // When collapsed (progress 0):
    //   Items > 0 are absolutely positioned relative to the container (which wraps them all).
    //   Item 0 is relative.
    // When expanded (progress 1):
    //   All items are relative.
    
    // To smooth this, we can use interpolate for translateY.
    
    return {
      zIndex: stackZIndex,
      opacity: interpolate(progress.value, [0, 1], [stackOpacity, 1]),
      transform: [
        {
          scale: interpolate(progress.value, [0, 1], [stackScale, 1]),
        },
        {
          translateY: interpolate(
             progress.value,
             [0, 1],
             [stackTranslateY, 0] // In stack, they go down. In list, translation is 0 (relative flow handles pos).
          ),
        },
      ],
    };
  });

  // Logic for positioning:
  // We'll use a container View for each card.
  // When collapsed, the container height for index > 0 should be 0?
  // That would pull them up.
  
  const containerStyle = useAnimatedStyle(() => {
     // We can animate the height of the wrapper view.
     // But we don't know the content height.
     // Assuming ~140px for card.
     const approxHeight = 140; 
     
     if (index === 0) return {}; // First card always takes space
     
     // For others:
     // Collapsed: height is 0 (so they stack on top of first one, roughly)
     // Expanded: height is 'auto' (we can't animate to auto easily in RN without LayoutAnimation)
     
     return {
        marginTop: interpolate(progress.value, [0, 1], [-approxHeight + STACK_OFFSET, 16], Extrapolation.CLAMP),
     };
  });
  
  // Using Layout Animation for the actual position change support
  // requires the parent to handle it.
  
  // Simpler Visual Hack:
  // When collapsed, we just set marginTop to a negative value that overlaps them.
  // Since MedicationCard is roughly constant height, we can tune this.
  // MedicationCard height is roughly 130-150.
  // Let's guess -130 + 12.
  
  const cardContainerStyle = useAnimatedStyle(() => {
    // We assume a fixed height for the negative margin calculation logic.
    // A better way is needed if heights vary wildly.
    // But for now, let's use a safe estimated overlap.
    const cardHeight = 140; 
    const collapsedMarginTop = index === 0 ? 0 : -(cardHeight - STACK_OFFSET);
    const expandedMarginTop = index === 0 ? 0 : 16;
    
    return {
       marginTop: interpolate(progress.value, [0, 1], [collapsedMarginTop, expandedMarginTop]),
       zIndex: total - index,
    };
  });

  return (
    <Animated.View style={[cardContainerStyle, style]}>
      {/* When collapsed, clicking any card should expand. When expanded, open details. */}
      {/* We can intercept touches if !isExpanded */}
      <View style={{ position: 'relative' }}>
        {/* Overlay to intercept clicks when collapsed */}
        {!isExpanded && (
           <TouchableOpacity
             style={[StyleSheet.absoluteFill, { zIndex: 100, elevation: 100 }]}
             onPress={onToggle}
             activeOpacity={0.9}
           />
        )}
        <MedicationCard
          medication={item}
          colors={colors}
          selectedDate={selectedDate}
          onOpenDetails={isExpanded ? onOpenDetails : undefined} // Disable inner click when collapsed
          onCelebrate={onCelebrate}
        />
      </View>
    </Animated.View>
  );
};

const styles = StyleSheet.create({
  container: {
    marginTop: 8,
    gap: 12,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingVertical: 8,
    paddingHorizontal: 4,
  },
  headerContent: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  iconContainer: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  headerTitle: {
    fontSize: 16,
    fontWeight: '600',
  },
  stackContainer: {
    position: 'relative',
    // minHeight ensures space for the stack when collapsed
  },
});