import Constants from 'expo-constants';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { useEffect, useState } from 'react';
import { Button, Platform, Text, View } from 'react-native';

Notifications.setNotificationHandler({
    handleNotification: async () => ({
        shouldPlaySound: false,
        shouldSetBadge: false,
        shouldShowBanner: true,
        shouldShowList: true,
    }),
});

export default function AuthNotifications({ setNotificationsEnabled, notificationsEnabled }: { setNotificationsEnabled: (value: boolean) => void, notificationsEnabled: boolean }) {
    const [expoPushToken, setExpoPushToken] = useState('');
    const [channels, setChannels] = useState<Notifications.NotificationChannel[]>([]);
    const [notification, setNotification] = useState<Notifications.Notification | undefined>(
        undefined
    );

    useEffect(() => {
        console.log('notificationsEnabled', notificationsEnabled);
        registerForPushNotificationsAsync().then(token => {
            console.log('token', token);
            token && setExpoPushToken(token)
        });

        if (Platform.OS === 'android') {
            Notifications.getNotificationChannelsAsync().then(value => setChannels(value ?? []));
        }
        const notificationListener = Notifications.addNotificationReceivedListener(notification => {
            setNotification(notification);
        });

        const responseListener = Notifications.addNotificationResponseReceivedListener(response => {
            console.log(response);
        });

        return () => {
            notificationListener.remove();
            responseListener.remove();
        };
    }, [notificationsEnabled]);

    return (
        <View
            style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'space-around',
                display: "none"
            }}>
            <Text>Your expo push token: {expoPushToken}</Text>
            <Text>{`Channels: ${JSON.stringify(
                channels.map(c => c.id),
                null,
                2
            )}`}</Text>
            <View style={{ alignItems: 'center', justifyContent: 'center' }}>
                <Text>Title: {notification && notification.request.content.title} </Text>
                <Text>Body: {notification && notification.request.content.body}</Text>
                <Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text>
            </View>
            <Button
                title="Press to schedule a notification"
                onPress={async () => {
                    await schedulePushNotification();
                }}
            />
        </View>
    );
}

async function schedulePushNotification() {
    await Notifications.scheduleNotificationAsync({
        content: {
            title: "You've got mail! 📬",
            body: 'Here is the notification body',
            data: { data: 'goes here', test: { test1: 'more data' } },
        },
        trigger: {
            type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
            seconds: 2,
        },
    });
}

async function registerForPushNotificationsAsync() {
    let token;

    // 1. Android 特定配置
    if (Platform.OS === 'android') {
        await Notifications.setNotificationChannelAsync('myNotificationChannel', {
            name: 'A channel is needed for the permissions prompt to appear',
            importance: Notifications.AndroidImportance.MAX,  // 最高优先级
            vibrationPattern: [0, 250, 250, 250],  // 振动模式
            lightColor: '#FF231F7C',  // 通知灯颜色
        });
    }

    // 2. 检查是否在真实设备上运行
    if (Device.isDevice) {
        // 3. 检查通知权限状态
        const { status: existingStatus } = await Notifications.getPermissionsAsync();
        let finalStatus = existingStatus;

        // 4. 如果尚未授予权限，则请求权限
        if (existingStatus !== 'granted') {
            const { status } = await Notifications.requestPermissionsAsync();
            finalStatus = status;
        }

        // 5. 如果权限被拒绝，显示警告并返回
        if (finalStatus !== 'granted') {
            alert('Failed to get push token for push notification!');
            return;
        }

        // 6. 获取推送令牌
        try {
            // 获取项目ID（用于Expo推送通知服务）
            const projectId =
                Constants?.expoConfig?.extra?.eas?.projectId ??
                Constants?.easConfig?.projectId;

            if (!projectId) {
                throw new Error('Project ID not found');
            }

            // 获取Expo推送令牌
            token = (
                await Notifications.getExpoPushTokenAsync({
                    projectId,
                })
            ).data;
            console.log(token);  // 打印令牌，实际应用中应该发送到你的服务器

        } catch (e) {
            token = `${e}`;  // 错误处理
        }
    } else {
        // 7. 如果是在模拟器上运行，显示警告
        alert('Must use physical device for Push Notifications');
    }

    return token;  // 返回获取到的令牌
}