import * as WebBrowser from 'expo-web-browser';
import { observer } from "mobx-react";
import React, { useEffect, useState } from "react";
import { ActivityIndicator, Alert, AppState, Image, ImageBackground, Platform, ScrollView, Text, TouchableNativeFeedback, TouchableOpacity, View } from 'react-native';
import { useAuth } from "../../hooks/useAuth";
import { useLandmarks } from "../../hooks/useLandmarks";
import { useProfile } from "../../hooks/useProfile";
import { authStore } from "../../stores/AuthStore";
import { API_URL, reportAxiosError } from '../../utils/RequestUtils';
import { ProfileMainStyles } from "./Styles/Profile.styles";
import { ProfileHeader } from "./ProfileHeader";
import { ProfileSections } from "./ProfileSections";
import { checkMultiple, PERMISSIONS, requestMultiple, RESULTS } from 'react-native-permissions';
import { colors, getMediaPermissions } from '../../utils/GlobalUtils';
import * as ImagePicker from 'expo-image-picker'
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types';
import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from 'react-native-popup-menu';
import axios from 'axios';
import { QueryClient } from 'react-query';
import { PhotoPicker } from '../PhotoPicker';
const {SlideInMenu} = renderers

/**
 * The screen component that displays the user's profile. Gets user information from the {@link useProfile} hook.
 * @component
 */
const Profile: React.FC = () => {
    const [changingPassword, toggleChangingPassword] = useState<boolean>(false) 
    const [photoSourceMenuOpened, togglePhotoSourceMenu] = useState<boolean>(false)
    const [newPhotoB64, setNewPhoto] = useState<string>()
    const [loadingImg, setLoadingImg] = useState<boolean>(false)
    const [uploadingImg, setUploadingImg] = useState<boolean>(false)
    const {
        profile, 
        changePasswordAsync, 
        changePasswordStatus, 
        resetChangePassword, 
        updateProfile, 
        updateProfileStatus, 
        resetUpdateProfile, 
        toggleTipsAsync, 
        refetchProfile
    } = useProfile(authStore.userId)
    
    useEffect(() => {
        if (newPhotoB64) {
            Alert.alert("Confirm new picture", "Are you sure you want to change your profile picture?", 
                [
                    {text: 'Yes', onPress: async () => await uploadPhoto()},
                    {text: 'No', onPress: cancelNewPhoto}
                ])   
            }
    }, [newPhotoB64])

    const initiateNewPhotoSelect = async () => {
        togglePhotoSourceMenu(false)
        setLoadingImg(true)
    }

    const onPhotoSelected = async (result: ImageInfo) => {
        setNewPhoto(result.base64)
        setLoadingImg(false)
    }

    const uploadPhoto = async () => {
        setUploadingImg(true)
        let photoData = new FormData()
        photoData.append('profPic', 'data:image/png;base64,' + newPhotoB64);

        try {
            const response = await axios({
              method: 'post',
              url: API_URL + '/api/user-profile/change-picture/' + authStore.userId + '/',
              headers: { "Authorization": "Bearer " + authStore.accessToken, },
              timeout: 50000,
              data: photoData,
            });
    
            if (response.status == 200) {
                await refetchProfile()
                Alert.alert("You successfully changed your profile picture!")
                setUploadingImg(false)
            }
            
        } catch (error) {
            console.log(error.response.data)
            reportAxiosError("Something went wrong when changing your profile picture", error, true)
            Alert.alert("Something went wrong when changing your profile picture.")
        }
    }

    const cancelNewPhoto = () => {
        togglePhotoSourceMenu(false)
        setNewPhoto('')
    }
    

    const PrivacyLink: React.FC = () => {
        /**
         * Opens up the company privacy policy in the browser.
         */
        const openPrivacyPolicy = async () => {
            await WebBrowser.openBrowserAsync(API_URL + "/privacy")
        }

        return (
            <TouchableOpacity onPress={openPrivacyPolicy}>
                <Text style={ProfileMainStyles.privacyButtonText}>Privacy policy</Text>
            </TouchableOpacity>
        )
    }
    const LogoutButton: React.FC = () => {
        const {logout} = useAuth()

        return (
            <TouchableOpacity style={ProfileMainStyles.logoutButtonContainer} onPress={async () => await logout()}>
                <Text style={ProfileMainStyles.logoutButtonText}>Logout</Text>
            </TouchableOpacity>
        )
    }

    return (
        <ImageBackground source={require('../../../assets/cover.jpg')} style={ProfileMainStyles.profileMainContainer}>
            <ScrollView contentContainerStyle={{justifyContent: "flex-end", alignItems: 'center', padding: 10}}>
                {loadingImg || uploadingImg ?
                <View style={{marginVertical: 30}}>
                    <Text style={{color: 'white', fontSize: 20, marginBottom: 10}}>{
                        loadingImg ? 'Loading image...' :
                        uploadingImg ? 'Uploading image' : null }
                    </Text>
                    <ActivityIndicator color='white' size="large"/> 
                </View> :
                <TouchableOpacity onPress={() => togglePhotoSourceMenu(true)} style={{zIndex: 10}}>
                    <Image style={ProfileMainStyles.profileImage} source={newPhotoB64 ? {uri: 'data:image/png;base64,' + newPhotoB64} : profile?.image_b64 ? {uri: 'data:image/png;base64,' + profile?.image_b64} : require('../../../assets/default-pfp.png')} /> 
                </TouchableOpacity> }
                
                <View style={ProfileMainStyles.profileSubContainer}>
                    <Text style={ProfileMainStyles.headerUsername}>{profile?.username}</Text>
                    <ProfileHeader profile={profile} />
                    <ProfileSections 
                        resetChangeInfo={resetUpdateProfile}
                        changeInfo={updateProfile}
                        changeInfoStatus={updateProfileStatus}
                        resetChangePassword={resetChangePassword}
                        changePasswordStatus={changePasswordStatus} 
                        profile={profile} 
                        toggleTipsAsync={toggleTipsAsync} 
                        changePassword={changePasswordAsync} />
                    <LogoutButton />
                    <PrivacyLink />
                </View>
            </ScrollView>
            <PhotoPicker multiple={false} menuType='alert' cancel={cancelNewPhoto} photoSourceMenuOpened={photoSourceMenuOpened} onBeforeLaunchPicker={initiateNewPhotoSelect} onReceivedPhotoResult={result => onPhotoSelected(result)} />
        </ImageBackground>
    )
}

export default observer(Profile)
