import React, {memo, useState, useMemo, useCallback} from "react";
import {StyleSheet} from "react-native";
import {Button, Picker, PickerModes, SegmentedControl, Text, View} from "react-native-ui-lib";
import {MaterialIcons} from "@expo/vector-icons";
import {useAtom} from "jotai";
import {format} from "date-fns";
import * as Device from "expo-device";
import {useIsFetching} from "@tanstack/react-query";

import {modeAtom, selectedDateAtom} from "@/components/pages/calendar/atoms";
import {months} from "./constants";
import RefreshButton from "@/components/shared/RefreshButton";
import {useCalSync} from "@/hooks/useCalSync";

type ViewMode = "day" | "week" | "month" | "3days";

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

const SEGMENTS = isTablet
    ? [{label: "D"}, {label: "W"}, {label: "M"}]
    : [{label: "D"}, {label: "3D"}, {label: "M"}];

const MODE_MAP = {
    tablet: ["day", "week", "month"],
    mobile: ["day", "3days", "month"]
} as const;

export const CalendarHeader = memo(() => {
    const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
    const [mode, setMode] = useAtom(modeAtom);
    const [tempIndex, setTempIndex] = useState<number | null>(null);

    const {resyncAllCalendars, isSyncing} = useCalSync();
    const isFetching = useIsFetching({queryKey: ['events']}) > 0;

    const isLoading = useMemo(() => isSyncing || isFetching, [isSyncing, isFetching]);

    const handleSegmentChange = useCallback((index: number) => {
        const modes = isTablet ? MODE_MAP.tablet : MODE_MAP.mobile;
        const selectedMode = modes[index] as ViewMode;

        setTempIndex(index);
        setTimeout(() => {
            setMode(selectedMode);
            setTempIndex(null);
        }, 150);
    }, [setMode]);

    const handleMonthChange = useCallback((month: string) => {
        const newMonthIndex = months.indexOf(month);
        const updatedDate = new Date(
            selectedDate.getFullYear(),
            newMonthIndex,
            selectedDate.getDate()
        );
        setSelectedDate(updatedDate);
    }, [selectedDate, setSelectedDate]);

    const handleRefresh = useCallback(async () => {
        try {
            await resyncAllCalendars();
        } catch (error) {
            console.error("Refresh failed:", error);
        }
    }, [resyncAllCalendars]);

    const getInitialIndex = useCallback(() => {
        const modes = isTablet ? MODE_MAP.tablet : MODE_MAP.mobile;
        //@ts-ignore
        return modes.indexOf(mode);
    }, [mode]);

    const renderMonthPicker = () => (
        <View row centerV gap-1 flexS>
            {isTablet && (
                <Text style={styles.yearText}>
                    {selectedDate.getFullYear()}
                </Text>
            )}
            <Picker
                value={months[selectedDate.getMonth()]}
                placeholder="Select Month"
                style={styles.monthPicker}
                mode={PickerModes.SINGLE}
                onChange={value => handleMonthChange(value as string)}
                trailingAccessory={<MaterialIcons name="keyboard-arrow-down"/>}
                topBarProps={{
                    title: selectedDate.getFullYear().toString(),
                    titleStyle: styles.yearText,
                }}
            >
                {months.map(month => (
                    <Picker.Item key={month} label={month} value={month}/>
                ))}
            </Picker>
        </View>
    );

    return (
        <View style={styles.container} flexG centerV>
            {mode !== "month" ? renderMonthPicker() : <View flexG/>}

            <View row centerV flexS>
                <Button
                    size="xSmall"
                    marginR-1
                    avoidInnerPadding
                    style={styles.todayButton}
                    onPress={() => setSelectedDate(new Date())}
                >
                    <MaterialIcons name="calendar-today" size={30} color="#5f6368"/>
                    <Text style={styles.todayDate}>{format(new Date(), "d")}</Text>
                </Button>

                <View style={styles.segmentContainer}>
                    <SegmentedControl
                        segments={SEGMENTS}
                        backgroundColor="#ececec"
                        inactiveColor="#919191"
                        activeBackgroundColor="#ea156c"
                        activeColor="white"
                        outlineColor="white"
                        outlineWidth={3}
                        segmentLabelStyle={styles.segmentLabel}
                        onChangeIndex={handleSegmentChange}
                        initialIndex={tempIndex ?? getInitialIndex()}
                    />
                </View>

                <RefreshButton onRefresh={handleRefresh} isSyncing={isLoading}/>
            </View>
        </View>
    );
});

const styles = StyleSheet.create({
    container: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        paddingVertical: isTablet ? 8 : 0,
        borderBottomLeftRadius: 0,
        borderBottomRightRadius: 0,
        paddingLeft: 10
    },
    yearText: {
        fontFamily: "Manrope_500Medium",
        fontSize: 17,
    },
    monthPicker: {
        fontFamily: "Manrope_500Medium",
        fontSize: 17,
        width: 85,
    },
    segmentContainer: {
        maxWidth: 120,
        height: 40,
    },
    segmentLabel: {
        fontSize: 12,
        fontFamily: "Manrope_600SemiBold",
    },
    todayButton: {
        backgroundColor: "transparent",
        borderWidth: 0,
        height: 30,
        width: 30,
        alignItems: 'center',
        justifyContent: 'center',
    },
    todayDate: {
        position: 'absolute',
        fontSize: 12,
        fontFamily: "Manrope_600SemiBold",
        color: "#5f6368",
        top: '30%',
    },
});