"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Chat = Chat;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const lucide_react_native_1 = require("lucide-react-native");
const react_1 = require("react");
const react_native_1 = require("react-native");
const react_native_gesture_handler_1 = require("react-native-gesture-handler");
const ReanimatedSwipeable_1 = tslib_1.__importDefault(require("react-native-gesture-handler/ReanimatedSwipeable"));
const react_native_reanimated_1 = tslib_1.__importStar(require("react-native-reanimated"));
const __1 = require("../../");
const atoms_1 = require("../../lib/theme/atoms");
const chat_message_1 = require("./chat-message");
const mod_view_1 = require("./mod-view");
const user_profile_card_1 = require("./user-profile-card");
function RightAction(prog, drag) {
    const styleAnimation = (0, react_native_reanimated_1.useAnimatedStyle)(() => {
        return {
            transform: [{ translateX: drag.value + 25 }],
        };
    });
    return ((0, jsx_runtime_1.jsx)(react_native_reanimated_1.default.View, { style: [styleAnimation], children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Reply, { color: "white" }) }));
}
function LeftAction(prog, drag) {
    const styleAnimation = (0, react_native_reanimated_1.useAnimatedStyle)(() => {
        return {
            transform: [{ translateX: drag.value - 25 }],
        };
    });
    return ((0, jsx_runtime_1.jsx)(react_native_reanimated_1.default.View, { style: [styleAnimation], children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Ellipsis, { color: "white" }) }));
}
// ios/android, 25, else 100 msgs
const SHOWN_MSGS = react_native_1.Platform.OS === "ios" || react_native_1.Platform.OS === "android" ? 25 : 100;
const keyExtractor = (item, index) => {
    return `${item.uri}`;
};
// Actions bar for larger screens
const ActionsBar = (0, react_1.memo)(({ item, visible, hoverTimeoutRef, }) => {
    const setReply = (0, __1.useSetReplyToMessage)();
    const setModMsg = (0, __1.usePlayerStore)((state) => state.setModMessage);
    if (!visible)
        return null;
    return ((0, jsx_runtime_1.jsxs)(__1.View, { style: [
            {
                position: "absolute",
                top: -14,
                right: 8,
                flexDirection: "row",
                backgroundColor: "rgba(180,180,180, 0.5)",
                borderRadius: 6,
                borderWidth: 1,
                padding: 1,
                gap: 4,
                zIndex: 10,
                maxWidth: 120,
                flexShrink: 0,
            },
        ], children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => setReply(item), style: [
                    {
                        padding: 6,
                        borderRadius: 4,
                        backgroundColor: "rgba(255, 255, 255, 0.1)",
                    },
                ], onHoverIn: () => {
                    // Keep the actions bar visible when hovering over it
                    if (hoverTimeoutRef.current) {
                        clearTimeout(hoverTimeoutRef.current);
                        hoverTimeoutRef.current = null;
                    }
                }, children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Reply, { color: "white", size: 16 }) }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => setModMsg(item), style: [
                    {
                        padding: 6,
                        borderRadius: 4,
                        backgroundColor: "rgba(255, 255, 255, 0.1)",
                    },
                ], onHoverIn: () => {
                    // Keep the actions bar visible when hovering over it
                    if (hoverTimeoutRef.current) {
                        clearTimeout(hoverTimeoutRef.current);
                        hoverTimeoutRef.current = null;
                    }
                }, children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Ellipsis, { color: "white", size: 16 }) })] }));
});
const ChatLine = (0, react_1.memo)(({ item }) => {
    const setReply = (0, __1.useSetReplyToMessage)();
    const setModMsg = (0, __1.usePlayerStore)((state) => state.setModMessage);
    const swipeableRef = (0, react_1.useRef)(null);
    const [isHovered, setIsHovered] = (0, react_1.useState)(false);
    const hoverTimeoutRef = (0, react_1.useRef)(null);
    const handleHoverIn = () => {
        if (hoverTimeoutRef.current) {
            clearTimeout(hoverTimeoutRef.current);
            hoverTimeoutRef.current = null;
        }
        setIsHovered(true);
    };
    const handleHoverOut = () => {
        hoverTimeoutRef.current = setTimeout(() => {
            setIsHovered(false);
        }, 50);
    };
    (0, react_1.useEffect)(() => {
        return () => {
            if (hoverTimeoutRef.current) {
                clearTimeout(hoverTimeoutRef.current);
            }
        };
    }, []);
    if (item.author.did === "did:sys:system") {
        return ((0, jsx_runtime_1.jsx)(__1.SystemMessage, { variant: (0, __1.getSystemMessageType)(item) || __1.SystemMessageType.notification, timestamp: new Date(item.record.createdAt), title: item.record.text, facets: item.record.facets }));
    }
    if (react_native_1.Platform.OS === "web") {
        return ((0, jsx_runtime_1.jsxs)(__1.View, { style: [
                atoms_1.py[1],
                atoms_1.px[2],
                {
                    position: "relative",
                    borderRadius: 8,
                    minWidth: 0,
                    maxWidth: "100%",
                },
                isHovered && atoms_1.bg.gray[950],
            ], onPointerEnter: handleHoverIn, onPointerLeave: handleHoverOut, children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { style: [{ minWidth: 0, maxWidth: "100%" }], children: (0, jsx_runtime_1.jsx)(chat_message_1.RenderChatMessage, { item: item }) }), (0, jsx_runtime_1.jsx)(ActionsBar, { item: item, visible: isHovered, hoverTimeoutRef: hoverTimeoutRef })] }));
    }
    return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(ReanimatedSwipeable_1.default, { containerStyle: [atoms_1.py[1]], friction: 2, enableTrackpadTwoFingerGesture: true, rightThreshold: 40, leftThreshold: 40, renderRightActions: react_native_1.Platform.OS === "android" ? undefined : RightAction, renderLeftActions: react_native_1.Platform.OS === "android" ? undefined : LeftAction, overshootFriction: 9, ref: swipeableRef, onSwipeableOpen: (r) => {
                if (r === (react_native_1.Platform.OS === "android" ? "right" : "left")) {
                    setReply(item);
                }
                if (r === (react_native_1.Platform.OS === "android" ? "left" : "right")) {
                    setModMsg(item);
                }
                // close this swipeable
                const swipeable = swipeableRef.current;
                if (swipeable) {
                    swipeable.close();
                }
            }, children: (0, jsx_runtime_1.jsx)(chat_message_1.RenderChatMessage, { item: item }) }) }));
});
function Chat({ shownMessages = SHOWN_MSGS, style: propsStyle, reverse = false, hideAfter, ...props }) {
    const { theme } = (0, __1.useTheme)();
    const chat = (0, __1.useChat)();
    const [isScrolledUp, setIsScrolledUp] = (0, react_1.useState)(false);
    const [isVisible, setIsVisible] = (0, react_1.useState)(true);
    const flatListRef = (0, react_1.useRef)(null);
    const latestMessageTime = chat?.[0]
        ? new Date(chat[0].record.createdAt).getTime()
        : null;
    // Animation for scroll-to-bottom button
    const buttonOpacity = (0, react_native_reanimated_1.useSharedValue)(0);
    const buttonTranslateY = (0, react_native_reanimated_1.useSharedValue)(20);
    (0, react_1.useEffect)(() => {
        buttonOpacity.value = (0, react_native_reanimated_1.withTiming)(isScrolledUp ? 1 : 0, { duration: 200 });
        buttonTranslateY.value = (0, react_native_reanimated_1.withTiming)(isScrolledUp ? 0 : 50, {
            duration: 200,
        });
    }, [isScrolledUp]);
    const buttonAnimatedStyle = (0, react_native_reanimated_1.useAnimatedStyle)(() => ({
        opacity: buttonOpacity.value,
        transform: [{ translateY: buttonTranslateY.value }],
    }));
    const scrollToBottom = () => {
        flatListRef.current?.scrollToOffset({ offset: 0, animated: true });
    };
    const scrollToTop = () => {
        flatListRef.current?.scrollToEnd({ animated: true });
    };
    const handleScroll = (event) => {
        const { contentOffset } = event.nativeEvent;
        const scrolledUp = contentOffset.y > 20; // threshold
        if (scrolledUp !== isScrolledUp) {
            setIsScrolledUp(scrolledUp);
            // Dismiss keyboard when scrolled up
            if (scrolledUp && react_native_1.Platform.OS !== "web") {
                react_native_1.Keyboard.dismiss();
            }
        }
    };
    (0, react_1.useEffect)(() => {
        if (!hideAfter || hideAfter <= 0)
            return;
        const referenceTime = latestMessageTime ?? Date.now();
        const delay = referenceTime + hideAfter * 1000 - Date.now();
        if (delay <= 0) {
            setIsVisible(false);
            return;
        }
        setIsVisible(true);
        const timer = setTimeout(() => {
            setIsVisible(false);
        }, delay);
        return () => clearTimeout(timer);
    }, [hideAfter, latestMessageTime]);
    if (!isVisible)
        return null;
    if (!chat)
        return ((0, jsx_runtime_1.jsx)(__1.View, { style: [atoms_1.flex.shrink[1], { minWidth: 0, maxWidth: "100%" }], children: (0, jsx_runtime_1.jsx)(__1.Text, { children: "Loading chat..." }) }));
    return ((0, jsx_runtime_1.jsxs)(__1.View, { style: [
            atoms_1.flex.values[1],
            {
                minWidth: 0,
                maxWidth: "100%",
                position: "relative",
                overflow: "visible",
            },
        ].concat(propsStyle || []), children: [(0, jsx_runtime_1.jsx)(user_profile_card_1.ProfileCardProvider, { children: (0, jsx_runtime_1.jsx)(react_native_gesture_handler_1.FlatList, { ref: flatListRef, style: [
                        atoms_1.flex.grow[1],
                        atoms_1.flex.shrink[1],
                        { minWidth: 0, maxWidth: "100%" },
                    ], data: chat.slice(0, shownMessages), inverted: !reverse, keyExtractor: keyExtractor, renderItem: ({ item, index }) => ((0, jsx_runtime_1.jsx)(__1.ErrorBoundary, { children: (0, jsx_runtime_1.jsx)(ChatLine, { item: item }) })), removeClippedSubviews: true, maxToRenderPerBatch: 10, initialNumToRender: 10, updateCellsBatchingPeriod: 50, onScroll: handleScroll, scrollEventThrottle: 16, nestedScrollEnabled: true }) }), (0, jsx_runtime_1.jsx)(react_native_reanimated_1.default.View, { style: [
                    {
                        position: "absolute",
                        bottom: 16,
                        left: 0,
                        right: 0,
                        alignItems: "center",
                        pointerEvents: isScrolledUp ? "box-none" : "none",
                    },
                    buttonAnimatedStyle,
                ], children: (0, jsx_runtime_1.jsxs)(react_native_1.Pressable, { onPress: reverse ? scrollToTop : scrollToBottom, style: [
                        {
                            pointerEvents: isScrolledUp ? "auto" : "none",
                            backgroundColor: theme.colors.primary,
                            opacity: 0.9,
                            borderRadius: 20,
                            shadowColor: "#000",
                            shadowOffset: { width: 0, height: 2 },
                            shadowOpacity: 0.25,
                            shadowRadius: 4,
                            elevation: 5,
                        },
                        atoms_1.layout.flex.row,
                        atoms_1.layout.flex.center,
                        atoms_1.px[2],
                        atoms_1.py[1],
                        { gap: 6 },
                    ], children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.ChevronDown, { size: 24, style: { marginTop: 2 }, color: "white" }), (0, jsx_runtime_1.jsx)(__1.Text, { style: [atoms_1.mr[1]], children: reverse ? "Scroll to top" : "Scroll to bottom" })] }) }), (0, jsx_runtime_1.jsx)(mod_view_1.ModView, {})] }));
}
//# sourceMappingURL=chat.js.map