import React, { useEffect, useState } from 'react';
import { SafeAreaView, ScrollView, StyleSheet, Switch, TouchableOpacity } from 'react-native';
import { useNavigation, NavigationProp } from '@react-navigation/native';
import { DateTimePickerAndroid, DateTimePickerEvent } from '@react-native-community/datetimepicker';
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';

import { Colors } from '@/src/constants/Colors';
import { useColorScheme } from '@/src/hooks/useColorScheme';
import { ThemedView } from '@/src/components/themed/ThemedView';
import { ThemedText } from '@/src/components/themed/ThemedText';
import { Request } from '@/src/services/request';
import { useToken } from '@/src/context/AppProvider';
import { Message } from '@/src/services/message';
import { store } from '@/src/store/store';
import { setSession } from '@/src/store/dataStore';
import { ThemedIcon } from '@/src/components/themed/ThemedIcon';

interface NotificationType {
    key: 'dayBefore' | 'sameDay' | 'pickup';
    label: string;
    defaultTime: string;
    minTime?: string;
    maxTime?: string;
}

interface NotificationsState {
    [ key: string ]: {
        enabled: boolean;
        time: string;
    };
}

export default function CategoryScreen() {
    const colorScheme = useColorScheme() ?? 'light';
    const navigation = useNavigation<NavigationProp<any>>();
    const { token } = useToken();
    const { t } = useTranslation();
    const session = useSelector( (state: any) => state.data.session );

    const [ sessionSet, setSessionSet ] = useState( false );

    const notificationTypes: NotificationType[] = [
        {
            key: 'dayBefore',
            label: t( "day-before" ),
            defaultTime: '19:30',
            minTime: '16:00',
        },
        {
            key: 'sameDay',
            label: t( "same-day" ),
            defaultTime: '08:00',
            maxTime: '09:00',
        },
        {
            key: 'pickup',
            label: t( "pickup" ),
            defaultTime: '17:30',
            minTime: '16:00',
        },
    ];

    const [ notifications, setNotifications ] = useState<NotificationsState>(
        notificationTypes.reduce( (acc, type) => {
            acc[ type.key ] = { enabled: true, time: type.defaultTime };
            return acc;
        }, {} as NotificationsState )
    );

    let currentEdit: keyof NotificationsState = 'dayBefore';

    // Set page title
    useEffect( () => {
        navigation.setOptions( { title: t( "notifications" ) } );
    }, [] );

    // Set session data
    useEffect( () => {
        if (!sessionSet) {
            const newNotifications = { ...notifications };

            notificationTypes.forEach( (type) => {
                const sessionTime = session.notifications[ type.key ];
                if (sessionTime === 'off') {
                    newNotifications[ type.key ].enabled = false;
                } else {
                    newNotifications[ type.key ].enabled = true;
                    newNotifications[ type.key ].time = sessionTime;
                }
            } );

            setNotifications( newNotifications );
            setSessionSet( true );
        }
    }, [ session ] );

    // Update session when something changes
    useEffect( () => {
        updateSession();
    }, [ notifications ] );

    // Open time picker
    const selectTime = (typeKey: keyof NotificationsState) => {
        currentEdit = typeKey;
        const time = new Date( `1970-01-01T${notifications[ typeKey ].time}` );

        if (time) {
            DateTimePickerAndroid.open( {
                value: time,
                onChange,
                mode: 'time',
                is24Hour: true,
                positiveButton: { label: t( "choose" ) },
                negativeButton: { label: t( "close" ) },
            } );
        }
    };

    // Set selected time
    const onChange = (event: DateTimePickerEvent, selectedDate?: Date) => {
        if (selectedDate) {
            const hours = selectedDate.getHours().toString().padStart( 2, '0' );
            const minutes = selectedDate.getMinutes().toString().padStart( 2, '0' );
            const timeString = `${hours}:${minutes}`;

            const notification = notificationTypes.find( nt => nt.key === currentEdit )!;

            if (notification.minTime) {
                const minDate = new Date( `1970-01-01T${notification.minTime}` );
                if (minDate > selectedDate) {
                    Message.error( t( "notifications-before-16-00" ) );
                    return;
                }
            } else if (notification.minTime) {
                const maxDate = new Date( `1970-01-01T${notification.minTime}` );
                if (maxDate < selectedDate) {
                    Message.error( t( "notifications-after-09-00" ) );
                    return;
                }
            }


            setNotifications( (prev) => ( {
                ...prev,
                [ currentEdit ]: { ...prev[ currentEdit ], time: timeString }
            } ) );
        }
    };

    // Enable/disable date
    const toggleDate = (typeKey: keyof NotificationsState) => {
        setNotifications( (prev) => ( {
            ...prev,
            [ typeKey ]: { ...prev[ typeKey ], enabled: !prev[ typeKey ].enabled }
        } ) );
    };

    // Update session data in API
    const updateSession = () => {
        if (!sessionSet) return;

        const postData: { token: string; [ key: string ]: string } = {
            token: token!,
        };

        notificationTypes.forEach( (type) => {
            postData[ `notification_${convertCase( type.key )}` ] = notifications[ type.key ].enabled ? notifications[ type.key ].time : 'off';
        } );

        Request.post( 'sessions/update', postData ).then( (response) => {
            if (response.success) {
                store.dispatch( setSession( response.session ) );
            } else {
                Message.error( t( "something-went-wrong" ) );
            }
        } );
    };

    // Convert camel case to snake case
    const convertCase = (camelCaseString: string) => {
        return camelCaseString
            .replace( /([A-Z])/g, '_$1' ) // Insert an underscore before each uppercase letter
            .toLowerCase();
    }

    return (
        <SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background }}>
            <ScrollView style={styles.container}>
                <ThemedView style={styles.listContainer}>
                    {notificationTypes.map( (type) => (
                        <ThemedView key={type.key} style={styles.listItem}>
                            <ThemedView style={styles.listTitle}>
                                <Switch
                                    trackColor={{ false: '#767577', true: Colors[ colorScheme ].tint }}
                                    thumbColor={'#fff'}
                                    value={notifications[ type.key ].enabled}
                                    style={styles.listSwitch}
                                    onValueChange={() => toggleDate( type.key )}
                                />
                                <ThemedText type="defaultSemiBold">{type.label}</ThemedText>
                            </ThemedView>

                            {notifications[ type.key ].enabled ? (
                                <TouchableOpacity style={styles.listEdit} onPress={() => selectTime( type.key )}>
                                    <ThemedText style={styles.listEditText}>{t( "at" )} {notifications[ type.key ].time}</ThemedText>
                                    <ThemedIcon size={18} name="chevron-forward" style={styles.listEditIcon}/>
                                </TouchableOpacity>
                            ) : (
                                <ThemedView style={styles.listEdit}>
                                    <ThemedText style={styles.listEditText}>{t( "off" )}</ThemedText>
                                </ThemedView>
                            )}
                        </ThemedView>
                    ) )}
                </ThemedView>
            </ScrollView>
        </SafeAreaView>
    );
}

const styles = StyleSheet.create( {
    container: {
        padding: 25,
    },
    listContainer: {
        paddingBottom: 10
    },
    listItem: {
        flex: 1,
        display: 'flex',
        gap: 8,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        paddingBottom: 20,
        marginBottom: 20,
        borderBottomWidth: 1,
        borderBottomColor: '#f2f2f2',
    },
    listTitle: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center',
    },
    listSwitch: {
        marginRight: 5,
    },
    listEdit: {
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'flex-end',
        textAlign: 'right',
    },
    listEditText: {
        fontWeight: '300',
    },
    listEditIcon: {
        marginLeft: 10,
    },
} );
