    import { FontAwesome } from "@expo/vector-icons";
    import React, { memo, useCallback, useEffect, useRef, useState } from "react";
    import { ActivityIndicator, Dimensions, Image, Keyboard, ListRenderItem, StyleSheet, Text, TextInput, View } from "react-native";
    import { ScrollView, TouchableWithoutFeedback } from "react-native-gesture-handler";
    import Picker from "react-native-picker-select";
    import { colors, Icons, IconStrings } from "../globals";
    import { Landmark, LMComment, useLandmarks } from "../hooks/useLandmarks";
    import { authStore } from "../stores/AuthStore";
    import { PrimaryButton } from "./Auth/Buttons";

    /**
     * Props for the {@link Comment} component.
     */
    export interface CommentProps {
        /**
         * The [comment]{@link LMComment} object being displayed by the {@link Comment} component.
         */
        comment: LMComment
    }

    /**
     * Component that displays a {@link LMComment} object in a clean format.
     * @component
     */
    export const Comment: React.FC<CommentProps> = ({comment}) => (
        <View>
            <Text testID="comment-text">{comment.text}</Text>
        </View>
    )

    /**
     * Props for the {@link LandmarkDetails} component.
     */
    export interface LandmarkDetailsProps {
        /**
         * The {@link Landmark} object being displayed/edited in the {@link LandmarkDetails} modal.
         */
        landmark: Landmark | undefined
        /**
         * A callback passed from the parent {@link Map} that toggles the visibility of the {@link LandmarkDetails} modal.
         */
        setVisible: (state: boolean) => void;
        /**
         * A callback passed from the parent {@link Map} that toggles the ability to edit the {@link Landmark} in {@link LandmarkDetails} modal.
         */
        setEditing: (state: boolean) => void;
        /**
         * A flag that determines whether the properties of the {@link Landmark} displayed in the {@link LandmarkDetails} modal can be edited
         */
        editingEnabled: boolean
    }

    /**
     * Component that renders the details of a selected {@link Landmark} and allows the user to edit those details. Contained within a [react-native-modal]{@link https://github.com/react-native-modal/react-native-modal}.
     * @component
     * @category Map
     */
    const LandmarkDetails: React.FC<LandmarkDetailsProps> = ({landmark, setVisible, setEditing, editingEnabled}) => {
        /**
         * Holds the state of the {@link Landmark} being displayed.
         */
        const selectedLandmarkState = undefined;
        const [selectedLandmark, setLandmark] = useState<Landmark | undefined>(selectedLandmarkState);
        /**
         * Holds state of a {@link Landmark} object parallel to {@linkcode selectedLandmarkState} that is manipulated when {@linkcode editingEnabled} is true.
         */
        const updatedLandmarkState = undefined;
        const [updatedLandmark, setUpdatedLandmark] = useState<Landmark | undefined>(updatedLandmarkState);
        const {
            updateLandmark, updateLandmarkStatus, resetUpdateLm,
            deleteLandmark, deleteLandmarkStatus, resetDeleteLm,
        } = useLandmarks(undefined);

        useEffect(() => {
            /**
             * Updates this component's {@linkcode selectedLandmarkState} when the {@linkcode landmark} prop passed down from the parent {@link Map}'s {@linkcode selectedLandmark} is changed.
             * Embedded in a useEffect that listens to the {@linkcode landmark} prop.
             * @memberOf LandmarkDetails
             */
            const updateLandmarkStateFromParent = () => {
                setLandmark(landmark)
            };
            updateLandmarkStateFromParent();
        }, [landmark])

        useEffect(() => {
            /**
             * Resets the {@linkcode updateLandmark} mutation on successful add.
             * Embedded in a useEffect that listens to the {@linkcode updateLandmarkStatus} value from the {@link useLandmarks} hook.
             * @memberOf LandmarkDetails
             */
             const resetUpdateMutationOnSuccess = () => {
                if (updateLandmarkStatus == 'success') {
                    resetUpdateLm();
                    setLandmark(updatedLandmark)
                }
            }
            resetUpdateMutationOnSuccess();
        }, [updateLandmarkStatus]);

        useEffect(() => {
            /**
             * Resets the {@linkcode deleteLandmark} mutation on successful delete.
             * Embedded in a useEffect that listens to the {@linkcode deleteLandmarkStatus} value from the {@link useLandmarks} hook.
             * @memberOf LandmarkDetails
             */
            const resetDeleteMutationOnSuccess = () => {
                if (deleteLandmarkStatus == 'success') {
                    resetDeleteLm();
                }
            }
            resetDeleteMutationOnSuccess();
        }, [deleteLandmarkStatus]);

        /**
         * Toggles whether or not the {@linkcode selectedLandmark} can be edited through the {@linkcode editingEnabled} prop.
         */
        const toggleEditing = (editingState: boolean) => {
            if (editingState) { setUpdatedLandmark(selectedLandmark); }
            else { setUpdatedLandmark(undefined); }
            setEditing(editingState);
        }

        /**
         * Calls the {@linkcode updateLandmark} mutation from the {@link useLandmarks} hook and closes the modal once finished.
         */
        const editLandmark = async () => {
            if (updatedLandmark) {
                await updateLandmark(updatedLandmark);
            }

            setEditing(false);
        }

        /**
         * Calls the {@linkcode deleteLandmark} mutation from the {@link useLandmarks} hook and closes the modal once finished.
         */
        const removeLandmark = async () => {
            await deleteLandmark(selectedLandmark?.id);
            setVisible(false);
        }

        /**
         * Renders all [comments]{@link LMComment} associated with the {@linkcode selectedLandmark} as items for the [FlatList]{@link https://reactnative.dev/docs/flatlist} in this component.
         */
        const renderComment: ListRenderItem<LMComment> = useCallback(({item}) => (
            <Comment comment={item} />
        ), []);

        return (
            <View style={[styles.container, editingEnabled ? {height: Dimensions.get("window").height * .4,} : {height: Dimensions.get("window").height * .4,}]}>
                {updateLandmarkStatus == "idle" && deleteLandmarkStatus == "idle" ?
                <>
                <View style={styles.detailsHeader}>
                    {authStore.userId !== selectedLandmark?.user ? null : !editingEnabled ?
                    <View style={{flexDirection: 'row', alignItems: "center"}}>
                        <FontAwesome style={{marginRight: 20, marginTop: 2}} size={25} color="white" name="edit" onPress={() => toggleEditing(true)}/>
                        <FontAwesome color="white" size={25} name="trash" onPress={async () => removeLandmark()}/>
                    </View> :
                    <View style={{flexDirection: 'row', alignItems: "center",}}>
                        <FontAwesome color="white" size={25} name="close" onPress={() => toggleEditing(false)}/>
                    </View>}
                    {!editingEnabled ?
                    <FontAwesome color="white" size={25} name="close" onPress={() => setVisible(false)}/>:
                    updatedLandmark?.description && updatedLandmark.landmark_type ?
                    <FontAwesome style={{marginTop: 2}} size={25} color="white" name="check" onPress={async () => editLandmark()}/> : null}
                </View>
                <View style={styles.detailsContainer}>
                    {editingEnabled ?
                    <View>
                        <View style={{flexDirection: 'row', marginBottom: 20, justifyContent: "space-between"}}>
                        {updatedLandmark?.landmark_type ?
                        <>
                        <Picker
                            style={{
                                inputIOS: {color: 'white'},
                                inputAndroid: {color: 'white'},
                                viewContainer: {marginVertical: 10, flex: 1}, placeholder: {color: 'white'}}}
                            textInputProps={{placeholderTextColor: 'white', selectionColor: 'white'}}
                            Icon={() => <FontAwesome name="chevron-down" color='white' size={20} />}
                            placeholder={
                                selectedLandmark?.landmark_type ?
                                    {label: IconStrings[selectedLandmark.landmark_type].toUpperCase(), value: selectedLandmark.landmark_type} :
                                    {label: "Select landmark type", value: 0} }
                            value={updatedLandmark.landmark_type}
                            onValueChange={(value) => {
                                setUpdatedLandmark({...updatedLandmark, landmark_type: value, title: IconStrings[value]})
                            }}
                            useNativeAndroidPickerStyle={true}
                            items={Object.keys(Icons)?.filter(icon => parseInt(icon) != selectedLandmark?.landmark_type).map(icon => {
                                return (
                                    {label: IconStrings[parseInt(icon)].toUpperCase(), value: icon, key: icon}
                                )})}
                        />
                        <Image style={{marginLeft: 20}} source={Icons[updatedLandmark.landmark_type]}/>
                        </>
                        : null}
                        </View>
                        <TouchableWithoutFeedback style={{marginBottom: 20}} onPress={() => Keyboard.dismiss()}>
                            <ScrollView style={{backgroundColor: 'white'}}>
                                <TextInput
                                    multiline={true}
                                    style={[styles.input, {fontSize: 13, marginBottom: 10}]}
                                    onChangeText={(value) => setUpdatedLandmark({...updatedLandmark, description: value})} >
                                    {updatedLandmark?.description}
                                </TextInput>
                            </ScrollView>
                        </TouchableWithoutFeedback>
                    </View>:
                    <View style={{flexDirection: 'row'}}>
                        <View style={{flex: 8, flexDirection: 'column', marginBottom: 20}}>
                            <Text style={{color: 'white', marginBottom: 10, fontSize: 15}}>{selectedLandmark?.title?.toUpperCase()}</Text>
                            <ScrollView>
                                <Text style={{color: 'white', fontSize: 13}}>{selectedLandmark?.description}</Text>
                            </ScrollView>
                        </View>
                        {selectedLandmark?.landmark_type ? <Image source={Icons[selectedLandmark.landmark_type]} /> : null}
                    </View>}
                    <TouchableWithoutFeedback style={{height: '100%'}} onPress={() => Keyboard.dismiss()}><Text></Text></TouchableWithoutFeedback>
                    {/* {!editingEnabled ?
                    <View style={styles.commentContainer}>
                        <Text style={{color: 'white', marginBottom: 20}}>Comments: </Text>
                        <FlatList<LMComment>
                            keyExtractor={i => i.id}
                            data={[
                                {id: '1', text: 'Hello', poster: 'chase'}, {id: '3', text: 'Hello', poster: 'chase'}, {id: '2', text: 'Hello', poster: 'chase'},
                                {id: '4', text: 'Hello', poster: 'chase'}, {id: '5', text: 'Hello', poster: 'chase'}, {id: '6', text: 'Hello', poster: 'chase'},
                                {id: '9', text: 'Hello', poster: 'chase'}, {id: '8', text: 'Hello', poster: 'chase'}, {id: '7', text: 'Hello', poster: 'chase'},
                                {id: '12', text: 'Hello', poster: 'chase'}, {id: '10', text: 'Hello', poster: 'chase'}, {id: '11', text: 'Hello', poster: 'chase'},
                            ]}
                            renderItem={renderComment}
                            style={{backgroundColor: 'white'}}/>

                    </View> : null} */}
                </View>
                </> :
                <View style={{height: '100%', justifyContent: "space-evenly", alignItems: "center", marginHorizontal: 20}}>
                    <Text style={{color: 'white', fontSize: 20}}>{
                        deleteLandmarkStatus == 'loading' ? "Deleting landmark..." :
                        deleteLandmarkStatus == 'error' ? "Something went wrong trying to delete the landmark" :
                        updateLandmarkStatus == 'loading' ? "Updating landmark..." :
                        updateLandmarkStatus == 'error' ? "Something went wrong trying to update the landmark" : null}
                    </Text>
                    {
                        deleteLandmarkStatus == 'loading' || updateLandmarkStatus == 'loading' ? <ActivityIndicator color='white' size="large"/> :
                        deleteLandmarkStatus == 'error' || updateLandmarkStatus == 'error' ? <PrimaryButton text="Okay" style={{borderColor: 'white', borderWidth: 1}} onPress={() => setVisible(false)} /> : null
                    }
                </View> }
            </View>
        )
    }

    const styles = StyleSheet.create({
        container: {
            backgroundColor: colors.red,
        },
        detailsHeader: {
            borderBottomWidth: 1,
            borderColor: 'white',
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
            backgroundColor: '#df3f3f',
            marginBottom: 10,
            paddingVertical: 10,
            paddingHorizontal: 20
        },
        detailsContainer: {
            flex: 1,
            marginHorizontal: 20
        },

        commentContainer: {
            flex: 5,
            marginBottom: 40
        },
        title: {

        },
        input: {
            padding: 5,
            color: 'black'
        }
    })

    export default memo(LandmarkDetails);