import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';
import { Platform } from 'react-native';
import { API_URL, APP_VERSION, WEBSOCKET_URL } from 'src/constants';
import axios from 'axios';
import { API } from 'src/types';
import { storage, StoreType } from 'src/storage';

const BACKGROUND_NOTIFICATION_TASK = 'BACKGROUND-NOTIFICATION-TASK';

TaskManager.defineTask(
  BACKGROUND_NOTIFICATION_TASK,
  async ({ data, error }: { data?: any; error?: any }) => {
    if (error) {
      return;
    }

    if (data) {
      const token = storage.get('token', StoreType.STRING);
      let groupToken;
      let messageId;
      let fromUser;

      groupToken = data?.data?.group_token;
      messageId = data?.data?.message_id;
      fromUser = data?.data?.from_user;

      if ((!groupToken && !fromUser) || !messageId) return;

      try {
        if (fromUser) {
          await axios.postForm(
            API_URL + '/' + API.MESSAGES_RECEIVED,
            {
              token,
              from_user: fromUser,
              messages_id: [messageId]
            },
            {
              headers: {
                Platform: Platform.OS,
                'App-Version': APP_VERSION
              }
            }
          );
        } else {
          await axios.postForm(
            API_URL + '/' + API.GROUP_MESSAGES_RECEIVED,
            {
              token,
              group_token: groupToken,
              messages_id: [messageId]
            },
            {
              headers: {
                Platform: Platform.OS,
                'App-Version': APP_VERSION
              }
            }
          );
        }

        const socket = new WebSocket(WEBSOCKET_URL);

        socket.onopen = () => {
          socket.send(JSON.stringify({ token }));
          let data: any = { action: 'messages_received', messages_ids: [messageId] };
          if (fromUser) {
            data.conversation_with = fromUser;
          } else {
            data.conversation_with_group = groupToken;
          }

          socket.send(JSON.stringify(data));
          socket.close();
        };

        socket.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
      } catch (err) {
        console.error('Error sending notification data:', err);
      }
    }
  }
);

export const registerBackgroundNotificationTask = async () => {
  try {
    const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_NOTIFICATION_TASK);

    if (!isRegistered && Platform.OS === 'ios') {
      await Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
    }
  } catch (error) {
    console.warn('Background notification task registration failed:', error);
  }
};

export const unregisterBackgroundNotificationTask = async () => {
  try {
    const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_NOTIFICATION_TASK);

    if (isRegistered) {
      await TaskManager.unregisterTaskAsync(BACKGROUND_NOTIFICATION_TASK);
    }
  } catch (error) {
    console.warn('Background notification task unregistration failed:', error);
  }
};

export const handleNotificationData = async (
  groupToken: string | undefined,
  messageId: number,
  fromUser: number | undefined
) => {
  const token = storage.get('token', StoreType.STRING);

  if ((!groupToken && !fromUser) || !messageId) return;

  try {
    if (fromUser) {
      await axios.postForm(
        API_URL + '/' + API.MESSAGES_RECEIVED,
        {
          token,
          from_user: fromUser,
          messages_id: [messageId]
        },
        {
          headers: {
            Platform: Platform.OS,
            'App-Version': APP_VERSION
          }
        }
      );
    } else {
      await axios.postForm(
        API_URL + '/' + API.GROUP_MESSAGES_RECEIVED,
        {
          token,
          group_token: groupToken,
          messages_id: [messageId]
        },
        {
          headers: {
            Platform: Platform.OS,
            'App-Version': APP_VERSION
          }
        }
      );
    }

    const socket = new WebSocket(WEBSOCKET_URL);

    socket.onopen = () => {
      socket.send(JSON.stringify({ token }));
      let data: any = { action: 'messages_received', messages_ids: [messageId] };
      if (fromUser) {
        data.conversation_with = fromUser;
      } else {
        data.conversation_with_group = groupToken;
      }

      socket.send(JSON.stringify(data));
      socket.close();
    };

    socket.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  } catch (err) {
    console.error('Error sending notification data:', err);
  }
};
