import { Formik } from "formik"
import React, { useEffect, useState } from "react"
import { ActivityIndicator, Button, StyleSheet, Text, TextInput, View, ViewStyle } from "react-native"
import { TouchableOpacity } from "react-native-gesture-handler"
import { colors, GlobalStyles } from "../../../utils/GlobalUtils"
import { PasswordForm, PasswordFormValues } from "../../PasswordForm"
import { ProfileSectionStyles } from "../Styles/ProfileSections.styles"
import { ProfileSection } from "./ProfileSection"
import * as Yup from 'yup';
import { PasswordFormStyles, PasswordValues } from "../../Auth/RegistrationSteps/RegisterPassword"
import { credsSchema, passwordSchema, profileCredsSchema, RegisterCredsValues } from "../../../utils/RegistrationUtils"
import { useProfile } from "../../../hooks/useProfile"
import { authStore } from "../../../stores/AuthStore"
import { Landmark } from "../../../hooks/useLandmarks"

interface ProfileInformationProps {
    openInfo: () => void
    infoCollapsed: boolean
    email: string
    username: string,
    changePassword: (password: string) => void
    changePasswordStatus: string
    resetChangePassword: () => void
    changeInfo: (info: RegisterCredsValues) => void
    changeInfoStatus: string
    resetChangeInfo: () => void
}

interface ChangePasswordValues {
    password: string;
    confirmPassword: string;
}

export const ProfileInformation: React.FC<ProfileInformationProps> = (props) => {
    const [editingEnabled, toggleEditing] = useState<boolean>(false)
    const [formUsername, setUsername] = useState<string>(props.username)
    const [formEmail, setEmail] = useState<string>(props.email)
    const [password, setPassword] = useState<string>()
    const [changingPassword, toggleChangingPassword] = useState<boolean>(false)
    const [confirmPassword, setConfirmPassword] = useState<string>()
    const initialPasswordValues: PasswordValues = {password: password, confirmPassword: confirmPassword};
    const initialInfoValues: RegisterCredsValues = {username: formUsername, email: formEmail};

    useEffect(() => {
        if (props.changeInfoStatus == "error") {
            setEmail(props.email)
            setUsername(props.username)
        }
    }, [props.changeInfoStatus])

    useEffect(() => {
        if (props.infoCollapsed) {   
            toggleEditing(false)
        }
    }, [props.infoCollapsed])

    useEffect(() => {
        if (!editingEnabled) {
            toggleChangingPassword(false)
            setPassword('')
            setConfirmPassword('')
        }
    }, [editingEnabled])

    useEffect(() => {
        if (props.email) {
            setEmail(props.email)
        }
    }, [props.email])

    useEffect(() => {
        if (props.username) {
            setUsername(props.username)
        }
    }, [props.username])

    const InformationRow: React.FC<{fieldName: string, value: string, setText?: (value: string) => void, editable?: boolean, style?: ViewStyle}> = ({fieldName, value, editable, setText, style}) => {
        return (
            <View style={[style,GlobalStyles.itemRowContainer]}>
                <Text>{fieldName}:</Text>
                {editable ? <TextInput value={value} onChangeText={text => setText(text)}/> : <Text>{value}</Text> }
            </View>
        )
    }

    const submitInfo = async (formValues: RegisterCredsValues) => {   
        await props.changeInfo(formValues)
        setEmail(formValues.email)
        setUsername(formValues.username)
    }

    const cancelEditingInfo = () => {
        props.resetChangeInfo()
        setUsername(props.username)
        setEmail(props.email)
        toggleEditing(false)
    }

    const submitNewPassword = async (formValues: PasswordFormValues) => {
        await props.changePassword(formValues.password)
    }

    const cancelChangingPassword = () => {
        props.resetChangePassword()
        setPassword('')
        setConfirmPassword('')
        toggleEditing(false)
    }

    const StatusIndicator: React.FC<{status: string, cancelHandler: () => void, updateTarget: string}> = ({status, cancelHandler, updateTarget}) => {
        return (
            <View style={{justifyContent: "space-evenly", alignItems: "center", marginHorizontal: 20}}>
                <Text style={{color: 'black', fontSize: 20}}>{
                    status == 'loading' ? "Updating..." : 
                    status == 'error' ? "Something went wrong trying to change your " + updateTarget : null} 
                </Text>
                {
                    status == "loading" ? <ActivityIndicator style={{marginBottom: 10}} color='black' size="large"/> :
                    status == "error" ? <Button title="Okay" color="gray" onPress={cancelHandler}/> : null
                }
            </View>
        )
    }

    const ChangePasswordForm: React.FC = React.memo(() => {
        return (
            <Formik
            initialValues={initialPasswordValues}
            validationSchema={passwordSchema}
            enableReinitialize={true}
            onSubmit={values => submitNewPassword(values)}>
            {({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
                <View style={{}}>
                    <TextInput 
                      style={{borderBottomWidth: 1, borderBottomColor: 'gray', marginBottom: 10, padding: 5}}
                      placeholder="New password" 
                      secureTextEntry={true} 
                      value={values.password}
                      onChangeText={handleChange('password')}
                      onBlur={handleBlur('password')} />
                    {errors.password && touched.password ? <Text style={PasswordFormStyles.errorText}>{errors.password}</Text> : null}
                    <TextInput 
                      style={{borderBottomWidth: 1, borderBottomColor: 'gray', marginBottom: 10, padding: 5}}
                      placeholder="Confirm password"
                      secureTextEntry={true} 
                      value={values.confirmPassword}
                      onChangeText={handleChange('confirmPassword')} 
                      onBlur={handleBlur('confirmPassword')} />
                    {errors.confirmPassword && touched.confirmPassword ? <Text style={PasswordFormStyles.errorText}>{errors.confirmPassword}</Text> : null}
                    <TouchableOpacity onPress={handleSubmit as any} style={styles.formButton}><Text style={{fontSize:17, color: 'dodgerblue'}}>Submit</Text></TouchableOpacity>
                    <TouchableOpacity onPress={cancelChangingPassword} style={styles.formButton}><Text style={{fontSize:17, color: colors.red}}>Cancel</Text></TouchableOpacity>
                </View>
              )}
        </Formik>
        )
    })

    const EditInfoForm: React.FC = () => {
        return (
            <Formik
                    initialValues={initialInfoValues}
                    validationSchema={profileCredsSchema}
                    enableReinitialize={true}
                    onSubmit={values => submitInfo(values)}>
                {({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
                    <View style={{}}>
                        <TextInput 
                          style={{borderBottomWidth: 1, borderBottomColor: 'gray', marginBottom: 10, padding: 5}}
                          placeholder="Email" 
                          value={values.email}
                          onChangeText={handleChange('email')}
                          onBlur={handleBlur('username')} />
                        {errors.email && touched.email ? <Text style={PasswordFormStyles.errorText}>{errors.email}</Text> : null}
                        <TextInput 
                          style={{borderBottomWidth: 1, borderBottomColor: 'gray', marginBottom: 10, padding: 5}}
                          placeholder="Username"
                          value={values.username}
                          onChangeText={handleChange('username')} 
                          onBlur={handleBlur('username')} />
                        {errors.username && touched.username ? <Text style={PasswordFormStyles.errorText}>{errors.username}</Text> : null}
                        <TouchableOpacity onPress={handleSubmit as any} style={styles.formButton}><Text style={{fontSize:17, color: 'dodgerblue'}}>Save changes</Text></TouchableOpacity>
                        <TouchableOpacity onPress={() => toggleChangingPassword(true)} style={styles.formButton}><Text style={{fontSize:17, color: 'dodgerblue'}}>Change password</Text></TouchableOpacity>
                        <TouchableOpacity onPress={cancelEditingInfo} style={styles.formButton}><Text style={{fontSize:17, color: colors.red}}>Cancel</Text></TouchableOpacity>
                    </View>
                  )}
                </Formik>
        )
    }

    return (
        <ProfileSection isCollapsed={props.infoCollapsed} collapseToggleMethod={props.openInfo} title="Information">
            {props.changePasswordStatus == "loading" || props.changePasswordStatus == "error" ? 
            <StatusIndicator status={props.changePasswordStatus} updateTarget="password" cancelHandler={cancelChangingPassword} /> :
            props.changeInfoStatus == "loading" || props.changeInfoStatus == "error" ? 
            <StatusIndicator status={props.changeInfoStatus} updateTarget="info" cancelHandler={cancelEditingInfo} /> :
            <>
                {changingPassword ? 
                <ChangePasswordForm /> : 
                <>
                    {editingEnabled && !changingPassword ? 
                    <EditInfoForm /> :
                    <>
                        <InformationRow style={{marginBottom: 10}} fieldName="Email" value={props.email}/>
                        <InformationRow style={{marginBottom: 20}} fieldName="Username" value={props.username} />
                        <TouchableOpacity onPress={() => toggleEditing(true)} style={styles.formButton}><Text style={{fontSize:17, color: 'dodgerblue'}}>Edit information</Text></TouchableOpacity>
                    </>}
                </>}
            </>}
        </ProfileSection>
    )
}

const styles = StyleSheet.create({
    formButton: {
        alignItems: 'center',
        padding: 5,
        borderRadius: 20,
        marginTop: 10
    },

    formInput: {
        borderBottomWidth: 1, 
        borderBottomColor: 'gray', 
        marginBottom: 10, padding: 5
    }
})