import { useState, useEffect, useRef } from "react"; import { View, TextInput, StyleSheet, TextInputProps, TouchableOpacity, Text, Animated, ViewStyle, } from "react-native"; import { gameUIColors } from "../ui/gameUI"; import { ChevronUp, ChevronDown, Trash } from "../icons"; interface CyberpunkInputProps extends TextInputProps { label?: string; containerStyle?: ViewStyle; showNumberControls?: boolean; onIncrement?: () => void; onDecrement?: () => void; showDeleteButton?: boolean; onDelete?: () => void; } export function CyberpunkInput({ label, containerStyle, showNumberControls = false, onIncrement, onDecrement, showDeleteButton = false, onDelete, ...props }: CyberpunkInputProps) { const [isFocused, setIsFocused] = useState(false); // Animated values for glitch effect const glitchOpacity = useRef(new Animated.Value(0)).current; const glitchX = useRef(new Animated.Value(0)).current; const glitchY = useRef(new Animated.Value(0)).current; const glitchScale = useRef(new Animated.Value(1)).current; const borderGlow = useRef(new Animated.Value(0.6)).current; useEffect(() => { if (isFocused) { // Border glow animation Animated.timing(borderGlow, { toValue: 1, duration: 200, useNativeDriver: true, }).start(); // Glitch opacity animation Animated.loop( Animated.sequence([ Animated.timing(glitchOpacity, { toValue: 0, duration: 2000, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0.8, duration: 30, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0, duration: 20, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0.6, duration: 40, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0, duration: 30, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0.4, duration: 20, useNativeDriver: true, }), Animated.timing(glitchOpacity, { toValue: 0, duration: 50, useNativeDriver: true, }), ]) ).start(); // Glitch X displacement Animated.loop( Animated.sequence([ Animated.timing(glitchX, { toValue: 0, duration: 2500, useNativeDriver: true, }), Animated.timing(glitchX, { toValue: 3, duration: 20, useNativeDriver: true, }), Animated.timing(glitchX, { toValue: -3, duration: 20, useNativeDriver: true, }), Animated.timing(glitchX, { toValue: 2, duration: 20, useNativeDriver: true, }), Animated.timing(glitchX, { toValue: 0, duration: 20, useNativeDriver: true, }), ]) ).start(); // Glitch Y displacement Animated.loop( Animated.sequence([ Animated.timing(glitchY, { toValue: 0, duration: 2200, useNativeDriver: true, }), Animated.timing(glitchY, { toValue: -2, duration: 30, useNativeDriver: true, }), Animated.timing(glitchY, { toValue: 1, duration: 20, useNativeDriver: true, }), Animated.timing(glitchY, { toValue: 0, duration: 30, useNativeDriver: true, }), ]) ).start(); // Glitch scale effect Animated.loop( Animated.sequence([ Animated.timing(glitchScale, { toValue: 1, duration: 3000, useNativeDriver: true, }), Animated.timing(glitchScale, { toValue: 1.01, duration: 20, useNativeDriver: true, }), Animated.timing(glitchScale, { toValue: 0.99, duration: 20, useNativeDriver: true, }), Animated.timing(glitchScale, { toValue: 1, duration: 20, useNativeDriver: true, }), ]) ).start(); } else { // Reset animations when not focused Animated.timing(borderGlow, { toValue: 0.6, duration: 200, useNativeDriver: true, }).start(); Animated.timing(glitchOpacity, { toValue: 0, duration: 100, useNativeDriver: true, }).start(); Animated.timing(glitchX, { toValue: 0, duration: 100, useNativeDriver: true, }).start(); Animated.timing(glitchY, { toValue: 0, duration: 100, useNativeDriver: true, }).start(); Animated.timing(glitchScale, { toValue: 1, duration: 100, useNativeDriver: true, }).start(); } }, [isFocused, borderGlow, glitchOpacity, glitchX, glitchY, glitchScale]); const handleFocus: NonNullable = (e) => { setIsFocused(true); props.onFocus?.(e); }; const handleBlur: NonNullable = (e) => { setIsFocused(false); props.onBlur?.(e); }; const containerAnimatedStyle = { opacity: borderGlow, borderColor: isFocused ? gameUIColors.info : gameUIColors.muted + "4D", }; const glitchAnimatedStyle = { opacity: glitchOpacity, transform: [ { translateX: glitchX }, { translateY: glitchY }, { scale: glitchScale }, ], }; return ( {/* Label */} {label && ( {label.toUpperCase()} )} {/* Input container */} {/* Glitch overlay when focused */} {/* Number control buttons */} {showNumberControls && ( )} {/* Delete button */} {showDeleteButton && ( )} {/* Corner accents */} ); } const styles = StyleSheet.create({ container: { width: "100%", marginVertical: 3, }, rowContainer: { flexDirection: "row", alignItems: "center", gap: 8, }, label: { fontSize: 10, fontWeight: "600", fontFamily: "monospace", color: gameUIColors.muted, letterSpacing: 0.5, minWidth: 60, }, labelFocused: { color: gameUIColors.info, }, inputContainer: { flex: 1, borderWidth: 1, borderRadius: 6, position: "relative", minHeight: 34, justifyContent: "center", flexDirection: "row", alignItems: "center", }, glitchOverlay: { position: "absolute", top: -1, left: -1, right: -1, bottom: -1, borderRadius: 6, borderWidth: 1, borderColor: gameUIColors.info, zIndex: 10, }, input: { flex: 1, paddingHorizontal: 10, paddingVertical: 6, color: gameUIColors.primaryLight, fontSize: 12, fontFamily: "monospace", backgroundColor: "transparent", zIndex: 1, }, inputWithControls: { paddingRight: 4, }, inputWithDelete: { paddingRight: 4, }, numberControls: { flexDirection: "row", gap: 2, paddingRight: 4, zIndex: 2, }, controlButton: { width: 28, height: 28, borderRadius: 6, borderWidth: 1, borderColor: gameUIColors.muted + "33", alignItems: "center", justifyContent: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.2, shadowRadius: 2, }, controlButtonFocused: { borderColor: gameUIColors.info + "CC", shadowColor: "#06B6D4", shadowOpacity: 0.3, shadowRadius: 4, }, deleteButton: { width: 28, height: 28, borderRadius: 6, borderWidth: 1, borderColor: gameUIColors.error + "4D", alignItems: "center", justifyContent: "center", shadowColor: "#EF4444", shadowOffset: { width: 0, height: 0 }, shadowOpacity: 0.15, shadowRadius: 3, marginRight: 4, zIndex: 2, }, deleteButtonFocused: { borderColor: gameUIColors.error + "CC", shadowOpacity: 0.3, shadowRadius: 5, }, cornerAccent: { position: "absolute", width: 6, height: 1.2, backgroundColor: gameUIColors.muted + "CC", zIndex: 0, }, cornerAccentFocused: { backgroundColor: gameUIColors.info, }, cornerTL: { top: -1, left: 5, }, cornerTR: { top: -1, right: 5, }, cornerBL: { bottom: -1, left: 5, }, cornerBR: { bottom: -1, right: 5, }, });