import React, { createContext, useContext, useEffect, useState, ReactNode } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { AppState } from "react-native";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
import log from "@/util/log"

export const API_URL = process.env.EXPO_PUBLIC_API_URL;

// Define context type
interface UserContextType {
    isProfileActive: boolean;
    setProfileActive: (active: boolean) => void;
    isMenuActive: boolean;
    setMenuActive: (active: boolean) => void;
    isAboutActive: boolean;
    setAboutActive: (active: boolean) => void;
    isPrivacyActive: boolean;
    setPrivacyActive: (active: boolean) => void;
    isBugActive: boolean;
    setBugActive: (active: boolean) => void;
    isLocationActive: boolean;
    setLocationActive: (active: boolean) => void;
    userId: string;
    userName: string;
    setUserName: (name: string) => void;
    userImage: string;
    setUserImage: (image: string) => void;
    userStatus: string;
    setUserStatus: (status: string) => void;
    setUserDataChanged: (changed: boolean) => void;
    isLoading: boolean;
    currentTheme: string;
    setTheme: (theme: string) => void;
}

// Create context with default values
const UserContext = createContext<UserContextType | undefined>(undefined);

// Define provider props type
interface UserProviderProps {
    children: ReactNode;
}

export const UserProvider: React.FC<UserProviderProps> = ({ children }) => {
    const [isProfileActive, setProfileActive] = useState(false);
    const [isMenuActive, setMenuActive] = useState(false);
    const [isAboutActive, setAboutActive] = useState(false);
    const [isPrivacyActive, setPrivacyActive] = useState(false);
    const [isBugActive, setBugActive] = useState(false);
    const [isLocationActive, setLocationActive] = useState(false);
    const [userId, setUserId] = useState("");
    const [userName, setUserName] = useState("");
    const [userImage, setUserImage] = useState("");
    const [userStatus, setUserStatus] = useState("none");
    const [userDataChanged, setUserDataChanged] = useState(false);
    const [isLoading, setIsLoading] = useState(true);
    const [appState, setAppState] = useState(AppState.currentState);
    const [currentTheme, setTheme] = useState("");

    useEffect(() => {
        const loadUserData = async () => {
            try {
                const storedUserId = await AsyncStorage.getItem("userId");
                const storedUserName = await AsyncStorage.getItem("userName");
                const storedUserImage = await AsyncStorage.getItem("userImage");
                const storedUserTheme = await AsyncStorage.getItem("theme");
                log.debug("Stored theme: ", storedUserTheme);
                if (storedUserId) {
                    setUserId(storedUserId);
                    setUserName(storedUserName || "");
                    setUserImage(storedUserImage || "");
                    setTheme(storedUserTheme || "blue");
                    setProfileActive(false);
                } else {
                    setUserId(uuidv4());
                    setUserName("");
                    setUserImage("");
                    setTheme("blue")
                    setProfileActive(true);
                }
            } catch (error) {
                log.error("Error loading user data:", error);
            } finally {
                setIsLoading(false);
            }
        };

        void loadUserData();
    }, []);

    useEffect(() => {
        if (!userDataChanged) return;

        const saveUserData = async () => {
            try {
                await AsyncStorage.setItem("userId", userId);
                await AsyncStorage.setItem("userName", userName);
                await AsyncStorage.setItem("userImage", userImage);
                await AsyncStorage.setItem("theme", currentTheme);
                log.debug("Current theme: ", currentTheme);
                setUserDataChanged(false);
            } catch (error) {
                log.error("Error saving user data:", error);
            }
        };

        void saveUserData();
    }, [userDataChanged]);

    useEffect(() => {
        const handleAppStateChange = (nextAppState: string) => {
            if (appState.match(/inactive|background/) && nextAppState === "active") {
                if (!isLoading) {
                    void fetchCurrentStatus();
                } else {
                    log.debug("Waiting for loading to complete before fetching status...");
                }
            }
            setAppState(AppState.currentState);
        };

        const listener = AppState.addEventListener("change", handleAppStateChange);

        return () => {
            listener.remove();
        };
    }, [appState]);

    const fetchCurrentStatus = async () => {
        try {
            const response = await axios.post(API_URL + "/get", { id: userId });
            if (response.data?.status) {
                setTimeout(() => {
                    setUserStatus("none");
                }, 0);
            }
        } catch (error) {
            log.error("Error fetching status:", error);
        }
    };

    return (
        <UserContext.Provider
            value={{
                isProfileActive,
                setProfileActive,
                isMenuActive,
                setMenuActive,
                isAboutActive,
                setAboutActive,
                isPrivacyActive,
                setPrivacyActive,
                isBugActive,
                setBugActive,
                isLocationActive,
                setLocationActive,
                userId,
                userName,
                setUserName,
                userImage,
                setUserImage,
                userStatus,
                setUserStatus,
                setUserDataChanged,
                isLoading,
                currentTheme,
                setTheme,
            }}
        >
            {children}
        </UserContext.Provider>
    );
};

// Custom hook to use context
export const useUser = (): UserContextType => {
    const context = useContext(UserContext);
    if (!context) {
        throw new Error("useUser must be used within a UserProvider");
    }
    return context;
};
