import React, {memo, useCallback, useMemo} from "react";
import {Drawer} from "expo-router/drawer";
import {
    DrawerContentComponentProps,
    DrawerContentScrollView,
    DrawerNavigationOptions,
    DrawerNavigationProp
} from "@react-navigation/drawer";
import {ImageBackground, Pressable, StyleSheet} from "react-native";
import {Button, ButtonSize, Text, View} from "react-native-ui-lib";
import * as Device from "expo-device";
import {DeviceType} from "expo-device";
import {useSetAtom} from "jotai";
import {Ionicons} from "@expo/vector-icons";
import {ParamListBase, RouteProp, Theme} from '@react-navigation/native';

import {useSignOut} from "@/hooks/firebase/useSignOut";
import {CalendarHeader} from "@/components/pages/calendar/CalendarHeader";
import DrawerButton from "@/components/shared/DrawerButton";
import DrawerIcon from "@/assets/svgs/DrawerIcon";
import NavGroceryIcon from "@/assets/svgs/NavGroceryIcon";
import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon";
import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon";
import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon";
import FeedbackNavIcon from "@/assets/svgs/FeedbackNavIcon";
import {
    isFamilyViewAtom,
    settingsPageIndex,
    toDosPageIndex,
    userSettingsView,
} from "@/components/pages/calendar/atoms";
import ViewSwitch from "@/components/pages/(tablet_pages)/ViewSwitch";

const isTablet = Device.deviceType === DeviceType.TABLET;

type DrawerParamList = {
    index: undefined;
    calendar: undefined;
    brain_dump: undefined;
    settings: undefined;
    grocery: undefined;
    reminders: undefined;
    todos: undefined;
    notifications: undefined;
    feedback: undefined;
};

type DrawerScreenNavigationProp = DrawerNavigationProp<DrawerParamList>;

interface DrawerButtonConfig {
    id: string;
    title: string;
    color: string;
    bgColor: string;
    icon: React.FC;
    route: keyof DrawerParamList;
}

const DRAWER_BUTTONS: DrawerButtonConfig[] = [
    {
        id: 'calendar',
        title: 'Calendar',
        color: 'rgb(7, 184, 199)',
        bgColor: 'rgb(231, 248, 250)',
        icon: NavCalendarIcon,
        route: 'calendar'
    },
    {
        id: 'grocery',
        title: 'Groceries',
        color: '#50be0c',
        bgColor: '#eef9e7',
        icon: NavGroceryIcon,
        route: 'grocery'
    },
    {
        id: 'feedback',
        title: 'Feedback',
        color: '#ea156d',
        bgColor: '#fdedf4',
        icon: FeedbackNavIcon,
        route: 'feedback'
    },
    {
        id: 'todos',
        title: 'To Dos',
        color: '#8005eb',
        bgColor: '#f3e6fd',
        icon: NavToDosIcon,
        route: 'todos'
    },
    {
        id: 'brain_dump',
        title: 'Brain Dump',
        color: '#e0ca03',
        bgColor: '#fffacb',
        icon: NavBrainDumpIcon,
        route: 'brain_dump'
    },
    {
        id: 'notifications',
        title: 'Notifications',
        color: '#ffa200',
        bgColor: '#ffdda1',
        icon: () => <Ionicons name="notifications-outline" size={24} color="#ffa200"/>,
        route: 'notifications'
    }
];

interface DrawerContentProps {
    props: DrawerContentComponentProps;
}

const DrawerContent: React.FC<DrawerContentProps> = ({props}) => {
    const {mutateAsync: signOut} = useSignOut();
    const setIsFamilyView = useSetAtom(isFamilyViewAtom);
    const setPageIndex = useSetAtom(settingsPageIndex);
    const setUserView = useSetAtom(userSettingsView);
    const setToDosIndex = useSetAtom(toDosPageIndex);

    const handleNavigation = useCallback((route: keyof DrawerParamList) => {
        props.navigation.navigate(route);
        setPageIndex(0);
        setToDosIndex(0);
        setUserView(true);
        setIsFamilyView(false);
    }, [props.navigation, setPageIndex, setToDosIndex, setUserView, setIsFamilyView]);

    const renderDrawerButtons = () => {
        const midPoint = Math.ceil(DRAWER_BUTTONS.length / 2);
        const leftButtons = DRAWER_BUTTONS.slice(0, midPoint);
        const rightButtons = DRAWER_BUTTONS.slice(midPoint);

        return (
            <View row paddingH-30>
                <View flex-1 paddingR-5>
                    {leftButtons.map(button => (
                        <DrawerButton
                            key={button.id}
                            title={button.title}
                            color={button.color}
                            bgColor={button.bgColor}
                            pressFunc={() => handleNavigation(button.route)}
                            icon={<button.icon/>}
                        />
                    ))}
                </View>
                <View flex-1>
                    {rightButtons.map(button => (
                        <DrawerButton
                            key={button.id}
                            title={button.title}
                            color={button.color}
                            bgColor={button.bgColor}
                            pressFunc={() => handleNavigation(button.route)}
                            icon={<button.icon/>}
                        />
                    ))}
                </View>
            </View>
        );
    };

    return (
        <DrawerContentScrollView {...props}>
            <View centerV marginH-30 marginT-20 marginB-20 row>
                <ImageBackground
                    source={require("../../assets/images/splash.png")}
                    style={styles.logo}
                />
                <Text style={styles.title}>Welcome to Cally</Text>
            </View>

            {renderDrawerButtons()}

            <Button
                onPress={() => handleNavigation('settings')}
                label="Manage Settings"
                labelStyle={styles.label}
                iconSource={() => (
                    <View style={styles.settingsIcon}>
                        <NavSettingsIcon/>
                    </View>
                )}
                backgroundColor="white"
                color="#464039"
                paddingV-30
                marginH-30
                borderRadius={18.55}
                style={{elevation: 0}}
            />

            <Button
                size={ButtonSize.large}
                style={styles.signOutButton}
                label="Sign out of Cally"
                color="#fd1775"
                labelStyle={styles.signOut}
                onPress={() => signOut()}
            />
        </DrawerContentScrollView>
    );
};

interface HeaderRightProps {
    route: RouteProp<DrawerParamList>;
    navigation: DrawerScreenNavigationProp;
}

const HeaderRight: React.FC<HeaderRightProps> = memo(({route, navigation}) => {
    const showViewSwitch = ["calendar", "todos", "index"].includes(route.name);
    const isCalendarPage = ["calendar", "index"].includes(route.name);

    if (!isTablet || !showViewSwitch) {
        return isCalendarPage ? <CalendarHeader/> : null;
    }

    return (
        <View marginR-16 row centerV>
            {isTablet && isCalendarPage && (
                <View flex-1 center>
                    <CalendarHeader/>
                </View>
            )}
            <ViewSwitch navigation={navigation}/>
        </View>
    )
});

interface DrawerScreen {
    name: keyof DrawerParamList;
    title: string;
    hideInDrawer?: boolean;
}

const DRAWER_SCREENS: DrawerScreen[] = [
    {name: 'index', title: 'Calendar'},
    {name: 'calendar', title: 'Calendar', hideInDrawer: true},
    {name: 'brain_dump', title: 'Brain Dump'},
    {name: 'settings', title: 'Settings'},
    {name: 'grocery', title: 'Groceries'},
    {name: 'reminders', title: 'Reminders'},
    {name: 'todos', title: isTablet ? 'Family To Dos' : 'To Dos'},
    {name: 'notifications', title: 'Notifications'},
    {name: 'feedback', title: 'Feedback'}
];

const TabLayout: React.FC = () => {
    const screenOptions = useMemo(() => {
        return ({route, navigation}: {
            route: RouteProp<ParamListBase, string>;
            navigation: DrawerNavigationProp<ParamListBase, string>;
            theme: Theme;
        }): DrawerNavigationOptions => ({
            lazy: true,
            headerShown: true,
            headerTitleAlign: "left",
            headerTitle: ({children}) => {
                const isCalendarRoute = ["calendar", "index"].includes(route.name);
                if (isCalendarRoute) return null;

                return (
                    <View flexG centerV paddingL-10>
                        <Text style={styles.headerTitle}>
                            {children}
                        </Text>
                    </View>
                );
            },
            headerLeft: () => (
                <Pressable
                    onPress={() => navigation.toggleDrawer()}
                    hitSlop={{top: 10, bottom: 10, left: 10, right: 10}}
                    style={({pressed}) => [styles.drawerTrigger, {opacity: pressed ? 0.4 : 1}]}
                >
                    <DrawerIcon/>
                </Pressable>
            ),
            headerRight: () => <HeaderRight
                route={route as RouteProp<DrawerParamList>}
                navigation={navigation as DrawerNavigationProp<DrawerParamList>}
            />,
            drawerStyle: styles.drawer,
        });
    }, []);


    return (
        <Drawer
            initialRouteName="index"
            detachInactiveScreens
            screenOptions={screenOptions}
            drawerContent={(props) => <DrawerContent props={props}/>}
        >
            {DRAWER_SCREENS.map(screen => (
                <Drawer.Screen
                    key={screen.name}
                    name={screen.name}
                    options={{
                        drawerLabel: screen.title,
                        title: screen.title,
                        ...(screen.hideInDrawer && {drawerItemStyle: {display: 'none'}}),
                    }}
                />
            ))}
        </Drawer>
    );
};

const styles = StyleSheet.create({
    drawer: {
        width: isTablet ? "30%" : "90%",
        backgroundColor: "#f9f8f7",
        height: "100%",
    },
    drawerTrigger: {
        marginLeft: 16,
    },
    headerTitle: {
        fontFamily: "Manrope_600SemiBold",
        fontSize: isTablet ? 22 : 17,
    },
    logo: {
        backgroundColor: "transparent",
        height: 51.43,
        aspectRatio: 1,
        marginRight: 8,
    },
    settingsIcon: {
        backgroundColor: "#ededed",
        width: 60,
        height: 60,
        borderRadius: 50,
        marginRight: 10,
        justifyContent: 'center',
        alignItems: 'center',
    },
    signOutButton: {
        marginTop: 50,
        marginHorizontal: 10,
        paddingVertical: 15,
        backgroundColor: "transparent",
        borderWidth: 1.3,
        borderColor: "#fd1775",
    },
    signOut: {
        fontFamily: "Poppins_500Medium",
        fontSize: 15,
    },
    label: {
        fontFamily: "Poppins_400Medium",
        fontSize: 15,
    },
    title: {
        fontSize: 26.13,
        fontFamily: "Manrope_600SemiBold",
        color: "#262627",
    },
});

export default TabLayout;