import React, { useEffect, useState } from 'react';
import { Platform, View, TouchableOpacity } from "react-native";
import { Button, TextInput, Dialog, Portal, Avatar, useTheme, Text } from "react-native-paper";
import { Asset } from 'expo-asset';
import * as FileSystem from 'expo-file-system';
import * as ImagePicker from "expo-image-picker";
import themes from '@/app/themes';
import styles from "@/app/styles";
import log from "@/util/log"
import featureFlags from '@/util/featureFlags';

interface ProfileScreenProps {
    visible: boolean;
    id: string;
    name: string;
    setName: (name: string) => void;
    image: string;
    setImage: (image: string) => void;
    setChanged: (dataChanged: boolean) => void;
    setTheme: (theme: string) => void;
    currentTheme: string;
    onClose: () => void;
}

const ProfileScreen: React.FC<ProfileScreenProps> = ({ visible, name, setName, image, setImage, setChanged, currentTheme, setTheme, onClose }) => {
    const theme = useTheme();
    const isNameEmpty = !name.trim();
    const themeColors = ['red', 'blue', 'yellow', 'green', 'orange', 'purple'];

    // Track the initial values when the component first mounts
    const [initialName, setInitialName] = useState(name);
    const [initialImage, setInitialImage] = useState(image);
    const [initialTheme, setInitialTheme] = useState(currentTheme);

    useEffect(() => {
        if (visible) {
            setInitialName(name);   // Store initial name when the profile opens
            setInitialImage(image);
            setInitialTheme(currentTheme)// Store initial image when the profile opens
        }
    }, [visible]); // Reset when the dialog is opened

    useEffect(() => {
        const loadDefaultImage = async () => {
            const asset = Asset.fromModule(require("../assets/images/default_profile_image.png"));
            await asset.downloadAsync();
            if (Platform.OS === 'web') {
                const response = await fetch(asset.uri);
                const blob = await response.blob();
                return new Promise((resolve) => {
                    const reader = new FileReader();
                    reader.onloadend = () => {
                        const base64String = reader.result?.toString().replace(/^data:.+;base64,/, '');
                        resolve(base64String);
                        if (typeof base64String == "string") {
                            setImage(base64String);
                        } else {
                            throw new Error("Failed to load asset.");
                        }
                    };
                    reader.readAsDataURL(blob);
                });
            } else if (asset.uri) {
                const base64 = await FileSystem.readAsStringAsync(asset.uri, { encoding: FileSystem.EncodingType.Base64 });
                setImage(base64);
            }
        };

        const loadImage = async () => {
            if (!image || image === "") {
                log.debug("Loading ", image);
                await loadDefaultImage();
            }
        };
        loadImage().then(() => null);
    }, [image]);

    const pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({ base64: true });
        if (!result.canceled && result.assets.length > 0) {
            if (result.assets[0].base64 !== image) {  // Only update if the image actually changes
                setImage(result.assets[0].base64 || image);
                log.debug("Picking Image");
            }
        }
    };

    const handleSave = () => {
        // Check if the name or image has changed
        const hasChanged = name !== initialName || image !== initialImage || currentTheme !== initialTheme;
        if (hasChanged) {
            setChanged(true);
        }
        onClose(); // Close the profile screen
    };

    return (
        <Portal>
            <Dialog
                visible={visible}
                onDismiss={() => {
                    if (!isNameEmpty) {  // Prevent closing if name is empty
                        onClose();
                    }
                }}
                style={{ backgroundColor: theme.colors.background }}>
                <Dialog.Title style={{ color: theme.colors.onBackground, textAlign: 'center', fontFamily: "Light"}}>Edit Your Profile</Dialog.Title>
                <Dialog.Content>
                    <Avatar.Image
                        size={100}
                        source={image ? { uri: `data:image/png;base64,${image}` } : require("../assets/images/default_profile_image.png")}
                        style={{ alignSelf: 'center', marginBottom: 15 }}
                    />
                    <Button
                        onPress={pickImage}
                        mode="contained"
                        style={{ backgroundColor: theme.colors.primaryContainer, marginBottom: 10 }}
                        labelStyle={{ color: theme.colors.primary, fontFamily: "SpaceReg" }}
                    >
                        Change Profile Picture
                    </Button>
                    <TextInput
                        label="Your Pet's Name"
                        mode="outlined"
                        value={name}
                        onChangeText={(newName) => {
                            if (newName !== name) {  // Only trigger change if it's different
                                setName(newName);
                                log.debug("Name change");
                            }
                        }}
                        style={{ marginBottom: 15, fontFamily: "SpaceReg" }}
                        placeholderTextColor={theme.colors.primary}
                        textColor={theme.colors.primary}
                        theme={{ colors: { text: theme.colors.primary }}}
                    />
                    {featureFlags.enableThemeSelection && (
                        <>
                    <Text style={{ color: theme.colors.primary, fontSize: 18, fontFamily: "SpaceReg", textAlign: 'center' }}>Choose Theme</Text>
                    <View style={styles.themeContainer}>
                        {themeColors.map((userTheme) => (
                            <TouchableOpacity
                                key={userTheme}
                                style={[styles.themeButton, { backgroundColor: themes[userTheme as keyof typeof themes]['light'].colors.primary }]}
                                onPress={() => {setTheme(userTheme); log.debug("Changing Theme: ", userTheme)}}
                            >
                                <View style={[styles.halfCircle, { backgroundColor: themes[userTheme as keyof typeof themes]['dark'].colors.primary }]} />
                            </TouchableOpacity>
                        ))}
                    </View>
                        </>
                    )}
                </Dialog.Content>
                <Dialog.Actions>
                    <Button
                        onPress={handleSave}
                        mode="contained"
                        disabled={isNameEmpty}  // Disable if name is empty
                        style={{
                            backgroundColor: theme.colors.primaryContainer,
                            opacity: isNameEmpty ? 0.5 : 1, // Visually dim the button
                        }}
                        labelStyle={{ color: theme.colors.primary, fontFamily: "SpaceReg" }}>Save</Button>
                </Dialog.Actions>
            </Dialog>
        </Portal>
    );
};

export default ProfileScreen;
