/* Copyright (C) Click & Push Accessibility, Inc - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 * Written and maintained by the Click & Push Development team 
 * <dev@clicknpush.ca>, January 2022
 */

import * as ImagePicker from "expo-image-picker"
import { ImageInfo } from "expo-image-picker/build/ImagePicker.types"
import React, { useEffect, useState } from "react"
import {Alert, AlertButton, Linking, Platform, Text} from 'react-native'
import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from "react-native-popup-menu"
import { colors, getMediaPermissions } from "../utils/GlobalUtils"
const {SlideInMenu} = renderers

export const PhotoPicker: React.FC<{photoSourceMenuOpened: boolean, cancel: () => void, onBeforeLaunchPicker?: () => void, onReceivedPhotoResult?: (result: ImageInfo) => void, menuType: 'slideup' | 'alert', multiple: boolean}> = ({photoSourceMenuOpened, cancel, onBeforeLaunchPicker, onReceivedPhotoResult, menuType, multiple}) => {

    useEffect(() => {
        if (photoSourceMenuOpened && menuType ==  'alert') {
            console.log("[PhotoPicker]: PhotoPicker is launching with menutype = " + menuType + " and multiple = " + multiple)
            showAlert()
        }
    }, [photoSourceMenuOpened])

    const showAlert = () => {
        if (Platform.OS == 'android') {
            Alert.alert(
                "Pick photo source", 
                "Where would like to get the photo from?",
                [
                    {text: 'Cancel', onPress: cancel, style: 'cancel'},
                    {text: 'Camera', onPress: () => selectNewPhoto('camera')},
                    {text: 'Library', onPress: () => selectNewPhoto('library')},
                ],
                {onDismiss: cancel, cancelable: true})
        }
        else if (Platform.OS == 'ios') {
            Alert.alert(
                "Pick photo source", 
                "Where would like to get the photo from?",
                [
                    {text: 'Camera', onPress: () => selectNewPhoto('camera')},
                    {text: 'Library', onPress: () => selectNewPhoto('library')},
                    {text: 'Cancel', onPress: cancel, style: 'cancel'},
                ],
                {onDismiss: cancel, cancelable: true})
        }

    }

    const selectNewPhoto = async (imageSource: 'camera' | 'library') => {
        if (onBeforeLaunchPicker) {
            onBeforeLaunchPicker()
        }
        
        console.log("[Permissions]: Checking photo permissions...")
        const granted = await getMediaPermissions();

        if (granted) {
            console.log("[Permissions]: Photo permissions are granted")
            const imageOptions: ImagePicker.ImagePickerOptions = {
                mediaTypes: ImagePicker.MediaTypeOptions.Images,
                base64: true,
                allowsEditing: true,
                quality: .5,
                allowsMultipleSelection: multiple
            }

            let result: ImagePicker.ImagePickerResult = {cancelled: true}

            try {
                if (imageSource === 'camera') {
                    console.log("[PhotoPicker]: Camera was selected as photo source, launching camera...")
                    result = await ImagePicker.launchCameraAsync(imageOptions)
                }
        
                if (imageSource === 'library') {
                    console.log("[PhotoPicker]: Image Library was selected as photo source, launching library...")
                    result = await ImagePicker.launchImageLibraryAsync(imageOptions)
                }   
                if (!result.cancelled) {
                    console.log("[PhotoPicker]: User selected image")
                    onReceivedPhotoResult(result as ImageInfo)
                }
                else {
                    console.log("[PhotoPicker]: User canceled image selection")
                    cancel()
                }
            } catch (error) {
                console.log("[PhotoPicker]: An error occurred during image selection: " + error)
                Alert.alert("Something went wrong when loading the selected image. Please try another image.")
                cancel()
            }
        }
        else {
            const permissionsButtons: AlertButton[] = [{text: 'Cancel', style: "cancel", onPress: cancel}]
            if (Platform.OS == 'ios')
                permissionsButtons.push({text: 'Go to settings', onPress: () => {
                    Linking.openURL('app-settings:')
                    cancel()
                }})
            Alert.alert(
                "Permissions needed", 
                "You need to grant camera/storage permissions to upload an image.",
                permissionsButtons,
                {onDismiss: cancel, cancelable: true})
        }
    }

    return (
        <>
        {menuType == 'slideup' ?
        <Menu renderer={SlideInMenu} style={{zIndex: 10}} opened={photoSourceMenuOpened} onBackdropPress={cancel} >
            <MenuTrigger />
            <MenuOptions optionsContainerStyle={{backgroundColor: colors.red}}>
                <MenuOption onSelect={async () => await selectNewPhoto('camera')} style={{padding: 20, alignItems: 'center', borderBottomWidth: 1, borderColor: 'white', marginHorizontal: 10}} >
                    <Text style={{fontSize: 20, color: 'white'}}>Select from camera</Text>
                </MenuOption>
                <MenuOption onSelect={async () => await selectNewPhoto('library')} style={{padding: 20, alignItems: 'center'}} >
                    <Text style={{fontSize: 20, color: 'white'}}>Select from library</Text>
                </MenuOption>
            </MenuOptions>
        </Menu> : null}
        </>
    )
}