import { ConstEnv } from '@/constants/ConstEnv';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { getApp, getApps, initializeApp } from '@react-native-firebase/app';
import {
   getMessaging,
   getToken as getMessagingToken,
   setAutoInitEnabled,
} from '@react-native-firebase/messaging';
import * as Notifications from 'expo-notifications';
import { useEffect } from 'react';
import { Linking, Platform } from 'react-native';

const RNfirebaseConfig = {
   apiKey: ConstEnv.firebase.apiKey,
   authDomain: ConstEnv.firebase.authDomain,
   projectId: ConstEnv.firebase.projectId,
   storageBucket: ConstEnv.firebase.storageBucket,
   messagingSenderId: ConstEnv.firebase.messagingSenderId,
   appId: ConstEnv.firebase.appId,
   databaseURL: ConstEnv.firebase.databaseURL
};

const initializeFirebase = async () => {
   try {
      let app;
      const apps = getApps();
      if (apps.length) {
         app = getApp() as any;
      } else {
         app = initializeApp(RNfirebaseConfig) as any;
      }
      const mess = getMessaging(app);
      await setAutoInitEnabled(mess, true);

      return mess;
   } catch (error) {
      console.error('Failed to initialize Firebase:', error);
   }
};

export const checkPermission = async () => {
   try {
      // Cek status permission sekarang
      const { status } = await Notifications.getPermissionsAsync();

      if (status === 'granted') {
         return true;
      }

      if (status === 'denied') {
         return false;
      }
   } catch (err) {
      console.warn('Error checking notification permissions:', err);
      return false;
   }
};

export const openSettings = () => {
   if (Platform.OS === 'ios') {
      Linking.openURL('app-settings:');
   } else {
      Linking.openSettings();
   }
};

export const requestPermission = async () => {
   try {
      const existing = await AsyncStorage.getItem('@notification_permission');
      const { status: currentStatus, canAskAgain } = await Notifications.getPermissionsAsync();

      // Jika baru pertama kali (fresh install / storage belum ada)
      if (existing === null) {
         // Cek apakah OS memungkinkan untuk memunculkan popup
         if (currentStatus === 'undetermined' || (currentStatus === 'denied' && canAskAgain)) {
            const { status: newStatus } = await Notifications.requestPermissionsAsync();
            await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? 'true' : 'false');
            return newStatus === 'granted';
         }

         // Jika OS sudah granted (sudah diijinkan entah lewat mana), simpan true
         if (currentStatus === 'granted') {
            await AsyncStorage.setItem('@notification_permission', 'true');
            return true;
         }

         // Jika OS denied dan tidak bisa minta lagi (disables)
         if (currentStatus === 'denied' && !canAskAgain) {
            await AsyncStorage.setItem('@notification_permission', 'false');
            return false;
         }
      }

      const osPermission = await checkPermission();
      // Jika sudah pernah di-request sebelumnya (storage sudah ada)
      // Selalu sinkronkan jika OS menyatakan Denied
      if (osPermission === false) {
         await AsyncStorage.setItem('@notification_permission', 'false');
         return false;
      }

      // Jika OS Granted, ikuti nilai tersimpan di storage (menghargai in-app toggle user)
      if (osPermission === true) {
         return existing === 'true';
      }

      return false;
   } catch (err) {
      console.warn('Error requesting notification permissions:', err);
      return false;
   }
};

export const getToken = async () => {
   try {
      const mess = await initializeFirebase();
      if (!mess) return null;

      // pakai modular API
      const token = await getMessagingToken(mess);
      return token;
   } catch (error) {
      console.error('Error getting token:', error);
   }
};

export const useNotification = () => {
   useEffect(() => {
      const initializeAndSetup = async () => {
         try {
            await getToken();
         } catch (error) {
            console.error('Failed to setup notifications:', error);
         }
      };

      initializeAndSetup();
   }, []);
};
