import { useEffect, useState } from 'react';
import {
  NOTIFICATION_MESSAGES_UPDATED_EVENT,
  deleteNotificationMessage,
  fetchNotificationMessage,
  fetchNotificationMessages,
  updateNotificationMessageReadState,
  type NotificationMessageItem,
  type NotificationMessageListStatus,
} from '../../notificationApi';
import { useUnreadCounts } from './useUnreadCounts';

function mergeMessageItem(items: NotificationMessageItem[], nextItem: NotificationMessageItem) {
  const hasItem = items.some((item) => item.id === nextItem.id);

  if (!hasItem) {
    return [nextItem, ...items];
  }

  return items.map((item) => (item.id === nextItem.id ? nextItem : item));
}

export function useNotificationCenterData(drawerOpen: boolean) {
  const [listStatus, setListStatus] = useState<NotificationMessageListStatus>('unread');
  const [detailOpen, setDetailOpen] = useState(false);
  const [messages, setMessages] = useState<NotificationMessageItem[]>([]);
  const [selectedMessage, setSelectedMessage] = useState<NotificationMessageItem | null>(null);
  const [listLoading, setListLoading] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [toggleReadLoading, setToggleReadLoading] = useState(false);
  const [deletingMessageId, setDeletingMessageId] = useState<number | null>(null);
  const [listError, setListError] = useState<string | null>(null);
  const [detailError, setDetailError] = useState<string | null>(null);
  const { notificationUnreadCount: unreadCount, refreshNotificationUnreadCount } = useUnreadCounts();

  const refreshUnreadCount = async () => {
    await refreshNotificationUnreadCount();
  };

  const loadMessages = async () => {
    setListLoading(true);
    setListError(null);

    try {
      const response = await fetchNotificationMessages({ status: listStatus, limit: 30 });
      setMessages(response.items);
    } catch (error) {
      setListError(error instanceof Error ? error.message : '알림 목록을 불러오지 못했습니다.');
    } finally {
      setListLoading(false);
    }
  };

  const applyUpdatedMessage = (nextItem: NotificationMessageItem) => {
    setSelectedMessage(nextItem);
    setMessages((current) => {
      const wasUnread = current.find((item) => item.id === nextItem.id)?.read === false;
      const nextItems =
        listStatus === 'unread' && nextItem.read
          ? current.filter((item) => item.id !== nextItem.id)
          : mergeMessageItem(current, nextItem);

      if (wasUnread !== nextItem.read) {
        void refreshNotificationUnreadCount();
      }

      return nextItems;
    });
  };

  const openMessageDetail = async (id: number) => {
    setDetailOpen(true);
    setDetailLoading(true);
    setDetailError(null);
    setSelectedMessage(null);

    try {
      const detail = await fetchNotificationMessage(id);
      setSelectedMessage(detail);

      if (!detail.read) {
        const updated = await updateNotificationMessageReadState(id, true);
        applyUpdatedMessage(updated);
      }
    } catch (error) {
      setDetailError(error instanceof Error ? error.message : '알림 상세를 불러오지 못했습니다.');
    } finally {
      setDetailLoading(false);
    }
  };

  const handleToggleReadState = async () => {
    if (!selectedMessage) {
      return;
    }

    setToggleReadLoading(true);

    try {
      const updated = await updateNotificationMessageReadState(selectedMessage.id, !selectedMessage.read);
      applyUpdatedMessage(updated);
    } catch (error) {
      setDetailError(error instanceof Error ? error.message : '읽음 상태를 변경하지 못했습니다.');
    } finally {
      setToggleReadLoading(false);
    }
  };

  const handleDeleteMessage = async (id: number) => {
    if (deletingMessageId === id) {
      return;
    }

    setDeletingMessageId(id);
    setListError(null);

    try {
      await deleteNotificationMessage(id);
      setMessages((current) => current.filter((item) => item.id !== id));
      void refreshNotificationUnreadCount();

      if (selectedMessage?.id === id) {
        setSelectedMessage(null);
        setDetailOpen(false);
      }
    } catch (error) {
      setListError(error instanceof Error ? error.message : '알림을 삭제하지 못했습니다.');
    } finally {
      setDeletingMessageId((current) => (current === id ? null : current));
    }
  };

  useEffect(() => {
    void refreshUnreadCount();

    const handleMessagesUpdated = () => {
      void refreshUnreadCount();

      if (drawerOpen) {
        void loadMessages();
      }
    };

    window.addEventListener(NOTIFICATION_MESSAGES_UPDATED_EVENT, handleMessagesUpdated);

    return () => {
      window.removeEventListener(NOTIFICATION_MESSAGES_UPDATED_EVENT, handleMessagesUpdated);
    };
  }, [drawerOpen, refreshNotificationUnreadCount]);

  useEffect(() => {
    if (!drawerOpen) {
      return;
    }

    void loadMessages();
  }, [drawerOpen, listStatus]);

  return {
    listStatus,
    setListStatus,
    unreadCount,
    detailOpen,
    setDetailOpen,
    messages,
    selectedMessage,
    listLoading,
    detailLoading,
    toggleReadLoading,
    deletingMessageId,
    listError,
    detailError,
    loadMessages,
    openMessageDetail,
    handleToggleReadState,
    handleDeleteMessage,
  };
}
