import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Animated, Platform, Dimensions } from 'react-native';
import { Swipeable, Gesture, GestureDetector, PanGestureHandler } from 'react-native-gesture-handler';
import { TaskData, SubtaskData, Priority, Repeat, Reminder } from '@/types';
import { PRIORITY_COLORS } from '@/constants';
import { useSettings } from '@/theme';
import Svg, { Path, Circle } from 'react-native-svg';

export type TaskLike = {
  id: string;
  title: string;
  priority: Priority;
  assigneeId: string | null;
  repeat: Repeat;
  allDay: boolean;
  completed: boolean;
  dueDate: number;
  dueTime: string;
  endTime: string;
  reminder: Reminder;
};

interface TaskItemProps {
  task: TaskData | SubtaskData | TaskLike;
  onToggle: () => void | Promise<void>;
  onDelete?: () => void;
  onPress: () => void;
  onLongPress?: () => void;
  onMenuOpen?: () => void;
  selected?: boolean;
  selectionMode?: boolean;
  completedSection?: boolean;
  draggable?: boolean;
  hovered?: boolean;
  onDragStart?: () => void;
  onDragUpdate?: (absoluteY: number) => void;
  onDragEnd?: (absoluteY: number) => void;
  onReorderStart?: () => void;
  onReorderUpdate?: (absoluteY: number) => void;
  onReorderEnd?: (absoluteY: number, translationY: number) => void;
  expanded?: boolean;
  indented?: boolean;
  depth?: number;
  categoryColor?: string;
  categoryColors?: (string | undefined)[];
}

export const TaskItem = React.memo(function TaskItem({ task, onToggle, onDelete, onPress, onLongPress, onMenuOpen, selected, selectionMode, completedSection, draggable, hovered, onDragStart, onDragUpdate, onDragEnd, onReorderStart, onReorderUpdate, onReorderEnd, expanded, indented, depth = 0, categoryColor, categoryColors }: TaskItemProps) {
  const { theme } = useSettings();
  const [opacityAnim] = React.useState(new Animated.Value(task.completed ? 0.5 : 1));
  const [dragTranslateX] = React.useState(new Animated.Value(0));
  const [dragTranslateY] = React.useState(new Animated.Value(0));
  const [dragging, setDragging] = React.useState(false);
  const [dragStartY, setDragStartY] = React.useState(0);
  const swipeableRef = React.useRef<Swipeable>(null);
  const [rotateAnim] = React.useState(new Animated.Value(0));

  React.useEffect(() => {
    Animated.timing(rotateAnim, {
      toValue: expanded ? 1 : 0,
      duration: 200,
      useNativeDriver: true,
    }).start();
  }, [expanded, rotateAnim]);

  const rotate = rotateAnim.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '180deg'] });

  const reorderGesture = React.useMemo(
    () =>
      Gesture.Pan()
        .activateAfterLongPress(400)
        .minDistance(5)
        .runOnJS(true)
        .onStart((e) => {
          setDragging(true);
          setDragStartY(e.absoluteY);
          onReorderStart?.();
        })
        .onUpdate((e) => {
          dragTranslateX.setValue(e.translationX);
          dragTranslateY.setValue(e.translationY);
          onReorderUpdate?.(e.absoluteY);
        })
        .onEnd((e) => {
          onReorderEnd?.(e.absoluteY, e.translationY);
        })
        .onFinalize(() => {
          setDragging(false);
          dragTranslateX.setValue(0);
          dragTranslateY.setValue(0);
        }),
    [onReorderStart, onReorderUpdate, onReorderEnd, dragTranslateX, dragTranslateY]
  );

  const dragGesture = React.useMemo(
    () =>
      Gesture.Pan()
        .activateAfterLongPress(400)
        .minDistance(2)
        .runOnJS(true)
        .onStart(() => {
          setDragging(true);
          onDragStart?.();
        })
        .onUpdate((e) => {
          dragTranslateX.setValue(e.translationX);
          dragTranslateY.setValue(e.translationY);
          onDragUpdate?.(e.absoluteY);
        })
        .onEnd((e) => {
          onDragEnd?.(e.absoluteY);
        })
        .onFinalize(() => {
          setDragging(false);
          dragTranslateX.setValue(0);
          dragTranslateY.setValue(0);
        }),
    [onDragStart, onDragUpdate, onDragEnd, dragTranslateX, dragTranslateY]
  );

  React.useEffect(() => {
    Animated.timing(opacityAnim, {
      toValue: task.completed ? 0.5 : 1,
      duration: 200,
      useNativeDriver: true,
    }).start();
  }, [task.completed, opacityAnim]);

  const dueInfo = React.useMemo(() => {
    const startOfToday = new Date();
    startOfToday.setHours(0, 0, 0, 0);
    const endOfToday = new Date();
    endOfToday.setHours(23, 59, 59, 999);
    const hasDueDate = task.dueDate > 0;
    const isOverdue = hasDueDate && !task.completed && task.dueDate < startOfToday.getTime();
    const isDueToday = hasDueDate && !task.completed && task.dueDate >= startOfToday.getTime() && task.dueDate <= endOfToday.getTime();
    return { hasDueDate, isOverdue, isDueToday };
  }, [task.dueDate, task.completed]);

  const { hasDueDate, isOverdue, isDueToday } = dueInfo;

  const formattedDueDate = React.useMemo(
    () => formatDueDate(task.dueDate, task.dueTime, task.endTime || ''),
    [task.dueDate, task.dueTime, task.endTime]
  );

  const renderRightActions = (progress: Animated.AnimatedInterpolation<number>) => {
    const translateX = progress.interpolate({ inputRange: [0, 1], outputRange: [80, 0] });
    return (
      <Animated.View style={[styles.swipeAction, styles.swipeDelete, { transform: [{ translateX }] }]}>
        <Svg width={24} height={24} viewBox="0 0 24 24">
          <Path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" stroke="#FFFFFF" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" fill="none" />
        </Svg>
        <Text style={styles.swipeActionText}>Delete</Text>
      </Animated.View>
    );
  };

const renderLeftActions = (progress: Animated.AnimatedInterpolation<number>) => {
    const translateX = progress.interpolate({ inputRange: [0, 1], outputRange: [-80, 0] });
    return (
      <Animated.View style={[styles.swipeAction, styles.swipeComplete, { transform: [{ translateX }] }]}>
        <Svg width={24} height={24} viewBox="0 0 24 24">
          <Path d="M5 12l5 5 9-10" stroke="#FFFFFF" strokeWidth={2.5} strokeLinecap="round" strokeLinejoin="round" fill="none" />
        </Svg>
        <Text style={styles.swipeActionText}>{task.completed ? 'Undo' : 'Done'}</Text>
      </Animated.View>
    );
  };

  return (
    <Swipeable
      ref={swipeableRef}
      renderRightActions={renderRightActions}
      renderLeftActions={renderLeftActions}
      onSwipeableRightOpen={() => {
        onDelete?.();
        swipeableRef.current?.close();
      }}
      onSwipeableLeftOpen={() => {
        onToggle();
        swipeableRef.current?.close();
      }}
      overshootRight={false}
      overshootLeft={false}
    >
      <GestureDetector gesture={draggable ? (onReorderStart ? reorderGesture : dragGesture) : Gesture.Native()}>
        <Animated.View
          style={[
            styles.container,
            { backgroundColor: theme.card, borderColor: theme.border },
            (indented || depth > 0) && { marginLeft: depth > 0 ? depth * 12 : 32, marginBottom: 4 },
            task.completed && styles.taskCompleted,
            isOverdue && styles.taskOverdue,
            isDueToday && styles.taskDueToday,
            selectionMode && styles.taskSelected,
            selected && { borderColor: theme.accent, borderWidth: 2 },
            completedSection && { backgroundColor: theme.cardAlt },
            dragging && styles.dragLifted,
            hovered && styles.taskHovered,
            { transform: [{ translateX: dragTranslateX }, { translateY: dragTranslateY }] },
          ]}
          pointerEvents={dragging ? 'none' : 'auto'}
        >
        <TouchableOpacity
          style={styles.contentWrapper}
          onPress={onPress}
          onLongPress={onLongPress}
          delayLongPress={350}
          activeOpacity={0.8}
          accessibilityRole={selectionMode ? 'checkbox' : 'button'}
          accessibilityLabel={selectionMode ? `Select ${task.title}` : task.title}
          accessibilityState={selectionMode ? { checked: selected } : { expanded }}
          accessibilityHint={selectionMode ? undefined : 'Expands the task to show subtasks'}
        >
<View style={styles.content}>
              <View style={styles.titleRow}>
                <View style={styles.categoryDotSlot}>
                  {(categoryColors ?? (categoryColor ? [categoryColor] : [])).slice(0, 3).map((color, i) => (
                    <View
                      key={`${color}-${i}`}
                      style={[
                        styles.categoryDot,
                        { backgroundColor: color },
                        i > 0 && { marginLeft: -6 },
                      ]}
                    />
                  ))}
                </View>
                <TouchableOpacity
                  style={styles.checkCircle}
                  onPress={onToggle}
                  activeOpacity={0.7}
                  accessibilityRole="checkbox"
                  accessibilityLabel={task.completed ? 'Mark incomplete' : 'Mark complete'}
                  accessibilityState={{ checked: task.completed }}
                >
                  <Svg width={30} height={30} viewBox="0 0 24 24">
                    {task.completed ? (
                      <>
                        <Circle cx={12} cy={12} r={10} fill={theme.accent} />
                        <Path d="M7 12l3 3 7-7" stroke="#FFFFFF" strokeWidth={2.5} strokeLinecap="round" strokeLinejoin="round" fill="none" />
                      </>
                    ) : (
                      <Circle cx={12} cy={12} r={10} stroke={isOverdue ? '#FF8A80' : theme.textSecondary} strokeWidth={2.5} fill="none" />
                    )}
                  </Svg>
                </TouchableOpacity>
                <Animated.Text
                  style={[
                    styles.title,
                    { color: theme.text },
                    task.completed && styles.titleCompleted,
                    isOverdue && styles.titleOverdue,
                  ]}
                >
                  {task.title}
                </Animated.Text>
              {task.priority !== 'none' && (
                <View
                  style={[
                    styles.priorityBadge,
                    { backgroundColor: PRIORITY_COLORS[task.priority] },
                  ]}
                >
                  <Text style={styles.priorityText}>
                    {task.priority.charAt(0).toUpperCase()}
                  </Text>
                </View>
              )}
              {task.assigneeId && (
                <View style={styles.assigneeBadge}>
                  <Text style={styles.assigneeText}>
                    {task.assigneeId.charAt(0).toUpperCase()}
                  </Text>
                </View>
              )}
              {task.repeat && task.repeat !== 'none' && (
                <View style={styles.repeatIcon}>
                  <Svg width={14} height={14} viewBox="0 0 24 24">
                    <Path
                      d="M17 2l4 4-4 4M3 11v-1a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 13v1a4 4 0 0 1-4 4H3"
                      stroke={theme.textSecondary}
                      strokeWidth={2.2}
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      fill="none"
                    />
                  </Svg>
                </View>
              )}
              {task.allDay && (
                <View style={styles.allDayBadge}>
                  <Svg width={14} height={14} viewBox="0 0 24 24">
                    <Path
                      d="M12 2v2M12 20v2M2 12h2M20 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M5.6 18.4l1.4-1.4M17 7l1.4-1.4"
                      stroke={theme.accent}
                      strokeWidth={1.8}
                      strokeLinecap="round"
                      fill="none"
                    />
                    <Circle cx={12} cy={12} r={4} stroke={theme.accent} strokeWidth={1.5} fill="none" />
                  </Svg>
                  <Text style={styles.allDayText}>All Day</Text>
                </View>
              )}
              <Animated.View style={[styles.chevron, { transform: [{ rotate }] }]}>
                <Svg width={16} height={16} viewBox="0 0 24 24">
                  <Path
                    d="M6 9l6 6 6-6"
                    stroke={theme.textSecondary}
                    strokeWidth={2.5}
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    fill="none"
                  />
                </Svg>
              </Animated.View>
            </View>
            {hasDueDate && (
              <View style={styles.dueRow}>
                <Svg width={14} height={14} viewBox="0 0 24 24">
                  <Circle cx={12} cy={12} r={10} stroke={theme.textSecondary} strokeWidth={2} fill="none" />
                  <Path d="M12 6v6l4 2" stroke={theme.textSecondary} strokeWidth={2} strokeLinecap="round" />
                </Svg>
                <Animated.Text
                  style={[
                    styles.dueText,
                    { color: theme.textFaint },
                    isOverdue && styles.dueTextOverdue,
                    isDueToday && styles.dueTextDueToday,
                  ]}
                >
                  {formattedDueDate}
                </Animated.Text>
                {task.reminder && task.reminder !== 'none' && (
                  <View style={styles.reminderIcon}>
                    <Svg width={13} height={13} viewBox="0 0 24 24">
                      <Path
                        d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10.3 21a1.94 1.94 0 0 0 3.4 0"
                        stroke={theme.textSecondary}
                        strokeWidth={1.8}
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        fill="none"
                      />
                    </Svg>
                  </View>
                )}
              </View>
            )}
          </View>
        </TouchableOpacity>

        <TouchableOpacity
          style={styles.menuButton}
          onPress={onMenuOpen}
          activeOpacity={0.7}
          accessibilityRole="button"
          accessibilityLabel={`Edit ${task.title}`}
          accessibilityHint="Opens the task editor"
          hitSlop={8}
        >
          <Svg width={24} height={24} viewBox="0 0 24 24">
            <Circle cx={12} cy={12} r={1.5} fill={theme.textMuted} />
            <Circle cx={12} cy={6} r={1.5} fill={theme.textMuted} />
            <Circle cx={12} cy={18} r={1.5} fill={theme.textMuted} />
          </Svg>
        </TouchableOpacity>
        </Animated.View>
      </GestureDetector>
    </Swipeable>
  );
});

function formatDueDate(dueDate: number, dueTime: string, endTime?: string): string {
  const date = new Date(dueDate);
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const tomorrow = new Date(today);
  tomorrow.setDate(tomorrow.getDate() + 1);

  let dateStr = '';
  if (date.getTime() === today.getTime()) {
    dateStr = 'Today';
  } else if (date.getTime() === tomorrow.getTime()) {
    dateStr = 'Tomorrow';
  } else {
    dateStr = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  }

  if (dueTime && endTime) {
    return `${dateStr} · ${formatTime12(dueTime)} – ${formatTime12(endTime)}`;
  }
  return dueTime ? `${dateStr} at ${formatTime12(dueTime)}` : dateStr;
}

function formatTime12(time: string): string {
  const [hours, minutes] = time.split(':').map(Number);
  if (Number.isNaN(hours) || Number.isNaN(minutes)) return time;
  const period = hours >= 12 ? 'PM' : 'AM';
  const h = hours % 12 === 0 ? 12 : hours % 12;
  return `${h}:${String(minutes).padStart(2, '0')} ${period}`;
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 12,
    paddingVertical: 14,
    borderRadius: 16,
    borderWidth: 1,
    marginVertical: 4,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.05,
    shadowRadius: 6,
    elevation: 1,
  },
  taskCompleted: {
    opacity: 0.5,
  },
  indented: {
    marginLeft: 32,
    marginBottom: 4,
  },
  taskOverdue: {
    borderColor: '#573431',
  },
  taskDueToday: {
    borderColor: '#2C4766',
  },
  taskSelected: {
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 6,
    elevation: 2,
  },
  taskHovered: {
    borderColor: '#2C4766',
    backgroundColor: 'rgba(44, 71, 102, 0.15)',
  },
  dragLifted: {
    zIndex: 100,
    elevation: 12,
    shadowColor: '#000',
    shadowOpacity: 0.25,
    shadowRadius: 12,
    shadowOffset: { width: 0, height: 8 },
  },
  contentWrapper: {
    flex: 1,
  },
  content: {
    gap: 12,
  },
  titleRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  dragHandle: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 8,
  },
  categoryDotSlot: {
    width: 28,
    height: 28,
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 8,
  },
  categoryDot: {
    width: 10,
    height: 10,
    borderRadius: 5,
  },
  title: {
    fontSize: 17,
    fontWeight: '500',
    flex: 1,
    marginRight: 16,
  },
  titleCompleted: {
    textDecorationLine: 'line-through',
    color: '#9E9E9E',
  },
  repeatIcon: {
    marginLeft: 8,
    width: 14,
    height: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  chevron: {
    marginLeft: 8,
    width: 16,
    height: 16,
    alignItems: 'center',
    justifyContent: 'center',
  },
  reminderIcon: {
    marginLeft: 6,
    width: 13,
    height: 13,
    alignItems: 'center',
    justifyContent: 'center',
  },
  titleOverdue: {
    color: '#E57373',
  },
  priorityBadge: {
    paddingHorizontal: 6,
    paddingVertical: 2,
    borderRadius: 8,
    minWidth: 20,
    alignItems: 'center',
  },
  priorityText: {
    fontSize: 9,
    fontWeight: '700',
    color: '#FFFFFF',
  },
  assigneeBadge: {
    width: 20,
    height: 20,
    borderRadius: 10,
    backgroundColor: '#43302E',
    alignItems: 'center',
    justifyContent: 'center',
  },
  assigneeText: {
    fontSize: 9,
    fontWeight: '700',
    color: '#FF9C8F',
  },
  dueRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  dueText: {
    fontSize: 13,
  },
  dueTextOverdue: {
    color: '#E57373',
    fontWeight: '600',
  },
  dueTextDueToday: {
    color: '#64B5F6',
    fontWeight: '600',
  },
  menuButton: {
    padding: 4,
    marginLeft: 8,
  },
  allDayBadge: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 4,
    marginLeft: 8,
    paddingHorizontal: 6,
    paddingVertical: 2,
    borderRadius: 8,
    backgroundColor: 'rgba(100, 181, 246, 0.15)',
  },
  allDayText: {
    fontSize: 11,
    fontWeight: '600',
    color: '#64B5F6',
  },
  checkCircle: {
    width: 30,
    height: 30,
    borderRadius: 15,
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 12,
  },
  swipeAction: {
    width: 80,
    alignItems: 'center',
    justifyContent: 'center',
    gap: 4,
  },
  swipeDelete: {
    backgroundColor: '#B8504A',
    borderTopRightRadius: 16,
    borderBottomRightRadius: 16,
  },
  swipeComplete: {
    backgroundColor: '#3D7A4A',
    borderTopLeftRadius: 16,
    borderBottomLeftRadius: 16,
  },
  swipeActionText: {
    color: '#FFFFFF',
    fontSize: 12,
    fontWeight: '600',
  },
});
