/**
 * Modal
 * Dependencies:
 * - @gorhom/bottom-sheet.
 *
 * Props:
 * - All `BottomSheetModalProps` props.
 * - `title` (string | undefined): Optional title for the modal header.
 *
 * Usage Example:
 * import { Modal, useModal } from '@gorhom/bottom-sheet';
 *
 * function DisplayModal() {
 *   const { ref, present, dismiss } = useModal();
 *
 *   return (
 *     <View>
 *       <Modal
 *         snapPoints={['60%']} // optional
 *         title="Modal Title"
 *         ref={ref}
 *       >
 *         Modal Content
 *       </Modal>
 *     </View>
 *   );
 * }
 *
 */

import type {
    BottomSheetBackdropProps,
    BottomSheetModalProps,
} from '@gorhom/bottom-sheet';
import { BottomSheetModal, useBottomSheet } from '@gorhom/bottom-sheet';
import * as React from 'react';
import { Pressable, View, Text } from 'react-native';
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
import { Path, Svg } from 'react-native-svg';
import {Icon, IconFamily} from "@/components/Icon";


type ModalProps = BottomSheetModalProps & {
    title?: string;
};

type ModalRef = React.ForwardedRef<BottomSheetModal>;

type ModalHeaderProps = {
    title?: string;
    dismiss: () => void;
};

export const useModal = () => {
    const ref = React.useRef<BottomSheetModal>(null);
    const present = React.useCallback((data?: any) => {
        ref.current?.present(data);
    }, []);
    const dismiss = React.useCallback(() => {
        ref.current?.dismiss();
    }, []);
    return { ref, present, dismiss };
};

export const Modal = React.forwardRef(
    (
        {
            snapPoints: _snapPoints = ['60%'],
            title,
            detached = false,
            ...props
        }: ModalProps,
        ref: ModalRef
    ) => {
        const detachedProps = React.useMemo(
            () => getDetachedProps(detached),
            [detached]
        );
        const modal = useModal();
        const snapPoints = React.useMemo(() => _snapPoints, [_snapPoints]);

        React.useImperativeHandle(
            ref,
            () => (modal.ref.current as BottomSheetModal) || null
        );

        const renderHandleComponent = React.useCallback(
            () => (
                <>
                    <View className="mb-8 mt-2 h-1 w-12 self-center rounded-lg bg-gray-400 dark:bg-gray-700" />
                    <ModalHeader title={title} dismiss={modal.dismiss} />
                </>
            ),
            [title, modal.dismiss]
        );

        return (
            <BottomSheetModal
                {...props}
                {...detachedProps}
                ref={modal.ref}
                index={0}
                snapPoints={snapPoints}
                backdropComponent={props.backdropComponent || renderBackdrop}
                handleComponent={renderHandleComponent}
            />
        );
    }
);

/**
 * Custom Backdrop
 */

const AnimatedPressable = Animated.createAnimatedComponent(Pressable);

const CustomBackdrop = ({ style }: BottomSheetBackdropProps) => {
    const { close } = useBottomSheet();
    return (
        <AnimatedPressable
            onPress={() => close()}
            entering={FadeIn.duration(50)}
            exiting={FadeOut.duration(20)}
            // eslint-disable-next-line react-native/no-inline-styles
            style={[style, { backgroundColor: 'rgba(0, 0, 0, 0.4)' }]}
        />
    );
};

export const renderBackdrop = (props: BottomSheetBackdropProps) => (
    <CustomBackdrop {...props} />
);

/**
 *
 * @param detached
 * @returns
 *
 * @description
 * In case the modal is detached, we need to add some extra props to the modal to make it look like a detached modal.
 */

const getDetachedProps = (detached: boolean) => {
    if (detached) {
        return {
            detached: true,
            bottomInset: 46,
            style: { marginHorizontal: 16, overflow: 'hidden' },
        } as Partial<BottomSheetModalProps>;
    }
    return {} as Partial<BottomSheetModalProps>;
};

/**
 * ModalHeader
 */

const ModalHeader = React.memo(({ title, dismiss }: ModalHeaderProps) => {
    return (
        <>
            {title && (
                <View className="flex-row px-2">
                    <View className="h-[24px] w-[24px]" />
                    <View className="flex-1">
                        <Text className="text-center text-[16px] font-bold text-[#26313D] dark:text-white">
                            {title}
                        </Text>
                    </View>
                </View>
            )}
            <CloseButton close={dismiss} />
        </>
    );
});

const CloseButton = ({ close }: { close: () => void }) => {
    return (
        <Pressable
            onPress={close}
            className="absolute right-3 top-3 h-[24px] w-[24px] items-center justify-center "
            hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
            accessibilityLabel="close modal"
            accessibilityRole="button"
            accessibilityHint="closes the modal"
        >
            <Icon
                family={IconFamily.MaterialCommunityIcons}
                name="close"
                size={25}
            />
        </Pressable>
    );
};
