import moment from 'moment';
import * as Notifications from 'expo-notifications';
import { Alert, Platform } from 'react-native';
import { NAVIGATION_PAGES } from 'src/types';
import { storage, StoreType } from 'src/storage';
import { Image as ImageCompressor, Video as VideoCompressor } from 'react-native-compressor';
import { FileSystem } from 'src/utils';
import Share from 'react-native-share';
import { APP_VERSION } from 'src/constants';

export const formatDate = (dateString: Date): string => {
  const inputDate = moment.utc(dateString).local();
  const today = moment().local();
  const yesterday = moment().local().subtract(1, 'days');

  if (inputDate.isSame(today, 'day')) {
    return inputDate.format('HH:mm');
  }
  if (inputDate.isSame(yesterday, 'day')) {
    return 'yesterday';
  }
  if (!inputDate.isSame(today, 'year')) {
    return inputDate.format('DD.MM.YYYY');
  }

  return inputDate.format('DD.MM');
};

export const dismissChatNotifications = async (
  chatWithUserId: number | string,
  isSubscribed: boolean,
  setModalInfo: (data: any) => void,
  navigation: any
) => {
  const { status } = await Notifications.getPermissionsAsync();
  const askedOnce = storage.get('askedNotificationPermission', StoreType.BOOLEAN) ?? false;

  if ((status !== 'granted' || !isSubscribed) && !askedOnce) {
    setModalInfo({
      visible: true,
      type: 'success',
      message:
        'To use this feature we need your permission to access your notifications. You will be redirected to the notification settings screen where you need to enable them.',
      action: () => {
        navigation.navigate(NAVIGATION_PAGES.NOTIFICATIONS);
        setModalInfo({ visible: false });
      }
    });
    storage.set('askedNotificationPermission', true);
    return;
  }

  const getNotificationData = (notification: Notifications.Notification) => {
    if (Platform.OS === 'android') {
      const data = notification.request.content.data;
      if (data?.params) {
        try {
          return JSON.parse(data?.params) ?? {};
        } catch (error) {
          console.error('Error parsing params:', error);
          return {};
        }
      } else {
        Notifications.dismissNotificationAsync(notification.request.identifier);
        return {};
      }
    } else {
      const data = (notification.request.trigger as Notifications.PushNotificationTrigger)?.payload;
      if (data?.params) {
        try {
          return JSON.parse(data.params as string) ?? {};
        } catch (error) {
          console.error('Error parsing params:', error);
          return {};
        }
      }
    }
  };

  const clearNotificationsFromUser = async (userId: number | string) => {
    const presentedNotifications = await Notifications.getPresentedNotificationsAsync();
    presentedNotifications.forEach((notification) => {
      const parsedParams = getNotificationData(notification);
      const conversation_with_user = parsedParams?.id ?? parsedParams?.group_token;

      if (conversation_with_user === userId) {
        Notifications.dismissNotificationAsync(notification.request.identifier);
      }
    });
  };

  await clearNotificationsFromUser(chatWithUserId);

  Notifications.setNotificationHandler({
    handleNotification: async (notification) => {
      let conversation_with_user = 0;
      const parsedParams = getNotificationData(notification);
      conversation_with_user = parsedParams?.id ?? parsedParams?.group_token;

      if (conversation_with_user === chatWithUserId) {
        return {
          shouldShowAlert: false,
          shouldShowBanner: false,
          shouldShowList: false,
          shouldPlaySound: false,
          shouldSetBadge: false
        };
      }

      return {
        shouldShowAlert: true,
        shouldShowBanner: true,
        shouldShowList: true,
        shouldPlaySound: false,
        shouldSetBadge: false
      };
    }
  });

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

export const isMessageEdited = (edits: string) => {
  try {
    const parsedEdits = JSON.parse(edits);
    return Array.isArray(parsedEdits) && parsedEdits.length > 0;
  } catch (error) {
    return false;
  }
};

export const compressImageWithProgress = (
  uri: string,
  onProgress: (p: number) => void
): Promise<string> => {
  return ImageCompressor.compress(uri, {
    compressionMethod: 'auto',
    progressDivider: 10,
    downloadProgress: (progress) => {
      onProgress(progress);
    }
  });
};

export const compressVideoWithProgress = (
  uri: string,
  onProgress: (p: number) => void
): Promise<string> => {
  return VideoCompressor.compress(uri, {}, (progress) => {
    onProgress(progress);
  });
};

export async function downloadImageFromViewer(uri: string, token: string) {
  if (!uri) return;

  try {
    if (uri.startsWith('file://')) {
      await Share.open({
        url: uri,
        failOnCancel: false
      });
      return;
    }

    const fileExt = 'jpg';
    const fileName = `image_${Date.now()}.${fileExt}`;
    const fileUri = `${FileSystem.cacheDirectory}${fileName}`;

    const { uri: localUri } = await FileSystem.downloadAsync(uri, fileUri, {
      headers: {
        Nmtoken: token,
        'App-Version': APP_VERSION,
        Platform: Platform.OS
      }
    });

    await Share.open({
      url: localUri,
      type: 'image/jpeg',
      failOnCancel: false
    });
  } catch (e) {
    Alert.alert('Error', 'Failed to save image');
  }
}
