import { memo, useEffect, useState } from 'react';
import { Pressable, StyleSheet, View } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withRepeat,
  withSequence,
  withTiming,
  cancelAnimation,
} from 'react-native-reanimated';
import { Text } from '@/aesthetics/Text';
import { radius, spacing, useColors } from '@/aesthetics/styles';
import { Plus, X } from 'lucide-react-native';
import type { MemoLogger } from './types';

const GAP = spacing.lg;
const MIN_TILE = 60;
const MAX_TILE = 76;
const ICON_SIZE = 30;
const LABEL_SIZE = 11;
const WIGGLE_DEG = 2;
const WIGGLE_MS = 160;

interface LoggerTileGridProps {
  memoLoggers: MemoLogger[];
  isLoading: boolean;
  isEditMode: boolean;
  onEnterEditMode: () => void;
  onExitEditMode: () => void;
  onSelect: (id: string) => void;
  onEdit?: (id: string) => void;
  onDelete: (id: string) => void;
  onAddNew: () => void;
  getLabel: (logger: MemoLogger) => string;
}

export function LoggerTileGrid({
  memoLoggers,
  isEditMode,
  onEnterEditMode,
  onExitEditMode,
  onSelect,
  onEdit,
  onDelete,
  onAddNew,
  getLabel,
}: LoggerTileGridProps) {
  const [tileSize, setTileSize] = useState(0);

  const handleLayout = (e: { nativeEvent: { layout: { width: number } } }) => {
    const width = e.nativeEvent.layout.width;
    const cols = Math.max(1, Math.floor((width + GAP) / (MIN_TILE + GAP)));
    const size = (width - GAP * (cols - 1)) / cols;
    setTileSize(Math.min(size, MAX_TILE));
  };

  const handleTilePress = (id: string) => {
    if (isEditMode && onEdit) {
      onEdit(id);
    } else {
      onSelect(id);
    }
  };

  return (
    <View style={styles.grid} onLayout={handleLayout}>
      {tileSize > 0 && (
        <>
          {memoLoggers.map((logger, i) => (
            <LoggerTile
              key={logger.id}
              logger={logger}
              label={getLabel(logger)}
              size={tileSize}
              isEditMode={isEditMode}
              index={i}
              onPress={() => handleTilePress(logger.id)}
              onLongPress={onEnterEditMode}
              onDelete={() => onDelete(logger.id)}
            />
          ))}
          <EditGridButton
            size={tileSize}
            isEditMode={isEditMode}
            onAdd={onAddNew}
            onDone={onExitEditMode}
          />
        </>
      )}
    </View>
  );
}

interface LoggerTileProps {
  logger: MemoLogger;
  label: string;
  size: number;
  isEditMode: boolean;
  index: number;
  onPress: () => void;
  onLongPress: () => void;
  onDelete: () => void;
}

const LoggerTile = memo(function LoggerTile({
  logger,
  label,
  size,
  isEditMode,
  index,
  onPress,
  onLongPress,
  onDelete,
}: LoggerTileProps) {
  const c = useColors();
  const rotation = useSharedValue(0);

  useEffect(() => {
    if (isEditMode) {
      const offset = index % 2 === 0 ? WIGGLE_DEG : -WIGGLE_DEG;
      rotation.value = withRepeat(
        withSequence(
          withTiming(offset, { duration: WIGGLE_MS }),
          withTiming(-offset, { duration: WIGGLE_MS })
        ),
        -1,
        true
      );
    } else {
      cancelAnimation(rotation);
      rotation.value = withTiming(0, { duration: WIGGLE_MS });
    }
  }, [isEditMode, index, rotation]);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ rotate: `${rotation.value}deg` }],
  }));

  return (
    <Animated.View style={[styles.tileWrapper, { width: size }, animatedStyle]}>
      <Pressable
        style={[styles.tile, { backgroundColor: c.loggerBg }]}
        onPress={onPress}
        onLongPress={onLongPress}
        delayLongPress={400}
      >
        <TileIcon icon={logger.icon} label={label} />
        {isEditMode && <DeleteButton onPress={onDelete} />}
      </Pressable>
      <Text style={[styles.label, { color: c.secondaryText }]} numberOfLines={1}>
        {label}
      </Text>
    </Animated.View>
  );
});

function TileIcon({ icon, label }: { icon?: string; label: string }) {
  const c = useColors();
  if (icon) {
    return <Text style={styles.emoji}>{icon}</Text>;
  }
  return <Text style={[styles.iconFallback, { color: c.logger }]}>{label.charAt(0)}</Text>;
}

function DeleteButton({ onPress }: { onPress: () => void }) {
  const c = useColors();
  return (
    <Pressable
      style={[styles.deleteBtn, { backgroundColor: c.danger }]}
      onPress={onPress}
      hitSlop={8}
    >
      <X size={10} color="#fff" strokeWidth={3} />
    </Pressable>
  );
}

interface EditGridButtonProps {
  size: number;
  isEditMode: boolean;
  onAdd: () => void;
  onDone: () => void;
}

function EditGridButton({ size, isEditMode, onAdd, onDone }: EditGridButtonProps) {
  const c = useColors();
  return (
    <View style={[styles.tileWrapper, { width: size }]}>
      <Pressable
        style={[styles.tile, styles.editButton, { borderColor: c.border }]}
        onPress={isEditMode ? onDone : onAdd}
      >
        {isEditMode ? (
          <Text style={[styles.doneLabel, { color: c.tertiaryText }]}>Done</Text>
        ) : (
          <Plus size={ICON_SIZE} color={c.tertiaryText} />
        )}
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  grid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: GAP,
  },
  tileWrapper: {
    alignItems: 'center',
    gap: spacing.xs,
  },
  tile: {
    aspectRatio: 1,
    width: '100%',
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  editButton: {
    borderWidth: 1.5,
    borderStyle: 'dashed',
  },
  emoji: {
    fontSize: ICON_SIZE,
  },
  iconFallback: {
    fontSize: ICON_SIZE,
    fontWeight: '600',
  },
  label: {
    fontSize: LABEL_SIZE,
    textAlign: 'center',
  },
  doneLabel: {
    fontSize: 13,
    fontWeight: '600',
  },
  deleteBtn: {
    position: 'absolute',
    top: -6,
    left: -6,
    width: 18,
    height: 18,
    borderRadius: 9,
    alignItems: 'center',
    justifyContent: 'center',
  },
});
