import React, { useCallback, useRef, useState } from "react";
import {
  View,
  ScrollView,
  TouchableOpacity,
  StyleSheet,
  Platform,
  type ViewStyle,
  type StyleProp,
  type NativeSyntheticEvent,
  type NativeScrollEvent,
  type LayoutChangeEvent,
} from "react-native";
import { ChevronLeft, ChevronRight } from "lucide-react-native";
import Colors from "@/constants/colors";
import { scrollViewWebProps } from "@/lib/ui/scroll-props";

interface HorizontalScrollRowProps {
  children: React.ReactNode;
  style?: StyleProp<ViewStyle>;
  contentContainerStyle?: StyleProp<ViewStyle>;
  /** Pixels to move per arrow tap. Defaults to ~3 quick-action tiles. */
  scrollStep?: number;
}

export function HorizontalScrollRow({
  children,
  style,
  contentContainerStyle,
  scrollStep = 280,
}: HorizontalScrollRowProps) {
  const scrollRef = useRef<ScrollView>(null);
  const scrollXRef = useRef(0);
  const [canScrollLeft, setCanScrollLeft] = useState(false);
  const [canScrollRight, setCanScrollRight] = useState(false);
  const [viewportWidth, setViewportWidth] = useState(0);
  const [contentWidth, setContentWidth] = useState(0);

  const updateArrows = useCallback(
    (x: number, viewW: number, contentW: number) => {
      const overflow = contentW - viewW;
      if (overflow <= 1) {
        setCanScrollLeft(false);
        setCanScrollRight(false);
        return;
      }
      setCanScrollLeft(x > 4);
      setCanScrollRight(x + viewW < contentW - 4);
    },
    []
  );

  const handleScroll = useCallback(
    (event: NativeSyntheticEvent<NativeScrollEvent>) => {
      const x = event.nativeEvent.contentOffset.x;
      scrollXRef.current = x;
      updateArrows(x, viewportWidth, contentWidth);
    },
    [contentWidth, updateArrows, viewportWidth]
  );

  const handleLayout = useCallback(
    (event: LayoutChangeEvent) => {
      const width = event.nativeEvent.layout.width;
      setViewportWidth(width);
      updateArrows(scrollXRef.current, width, contentWidth);
    },
    [contentWidth, updateArrows]
  );

  const handleContentSizeChange = useCallback(
    (width: number) => {
      setContentWidth(width);
      updateArrows(scrollXRef.current, viewportWidth, width);
    },
    [updateArrows, viewportWidth]
  );

  const scrollBy = useCallback(
    (delta: number) => {
      const maxX = Math.max(0, contentWidth - viewportWidth);
      const next = Math.max(0, Math.min(scrollXRef.current + delta, maxX));
      scrollRef.current?.scrollTo({ x: next, animated: true });
      scrollXRef.current = next;
      updateArrows(next, viewportWidth, contentWidth);
    },
    [contentWidth, updateArrows, viewportWidth]
  );

  const showArrows = canScrollLeft || canScrollRight;

  return (
    <View style={[styles.wrapper, style]} onLayout={handleLayout}>
      <ScrollView
        ref={scrollRef}
        horizontal
        nestedScrollEnabled
        showsHorizontalScrollIndicator={scrollViewWebProps.showsHorizontalScrollIndicator}
        scrollEventThrottle={16}
        onScroll={handleScroll}
        onContentSizeChange={handleContentSizeChange}
        contentContainerStyle={contentContainerStyle}
        style={styles.scroll}
        {...(Platform.OS === "web"
          ? ({
              // Shift + wheel / trackpad horizontal scroll on desktop web
              onWheel: (event: { shiftKey?: boolean; deltaX?: number; deltaY?: number; preventDefault?: () => void }) => {
                const deltaX = event.deltaX ?? 0;
                const deltaY = event.deltaY ?? 0;
                if (Math.abs(deltaX) > 2) {
                  event.preventDefault?.();
                  scrollBy(deltaX);
                } else if (event.shiftKey && Math.abs(deltaY) > 2) {
                  event.preventDefault?.();
                  scrollBy(deltaY);
                }
              },
            } as object)
          : {})}
      >
        {children}
      </ScrollView>

      {showArrows && canScrollLeft ? (
        <TouchableOpacity
          style={[styles.arrowHit, styles.arrowLeft]}
          onPress={() => scrollBy(-scrollStep)}
          accessibilityRole="button"
          accessibilityLabel="Scroll left"
          activeOpacity={0.85}
        >
          <View style={styles.arrowButton}>
            <ChevronLeft size={20} color={Colors.dark.text} />
          </View>
        </TouchableOpacity>
      ) : null}

      {showArrows && canScrollRight ? (
        <TouchableOpacity
          style={[styles.arrowHit, styles.arrowRight]}
          onPress={() => scrollBy(scrollStep)}
          accessibilityRole="button"
          accessibilityLabel="Scroll right"
          activeOpacity={0.85}
        >
          <View style={styles.arrowButton}>
            <ChevronRight size={20} color={Colors.dark.text} />
          </View>
        </TouchableOpacity>
      ) : null}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    position: "relative",
  },
  scroll: {
    width: "100%",
  },
  arrowHit: {
    position: "absolute",
    top: 0,
    bottom: 0,
    width: 36,
    justifyContent: "center",
    alignItems: "center",
    zIndex: 2,
  },
  arrowLeft: {
    left: 0,
  },
  arrowRight: {
    right: 0,
  },
  arrowButton: {
    width: 32,
    height: 32,
    borderRadius: 16,
    backgroundColor: Colors.dark.surfaceElevated,
    borderWidth: 1,
    borderColor: Colors.dark.border,
    alignItems: "center",
    justifyContent: "center",
    ...Platform.select({
      web: {
        boxShadow: "0 2px 8px rgba(0,0,0,0.35)",
        cursor: "pointer",
      } as object,
      default: {
        shadowColor: "#000",
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.25,
        shadowRadius: 4,
        elevation: 4,
      },
    }),
  },
});
