// @flow
import * as ICONS from 'constants/icons';
import React from 'react';
import Page from 'component/page';
import Spinner from 'component/spinner';
import { FormField } from 'component/common/form';
import Notification from 'component/notification';
import Button from 'component/button';
import usePersistedState from 'effects/use-persisted-state';
import Yrbl from 'component/yrbl';
import * as NOTIFICATIONS from 'constants/notifications';
import useFetched from 'effects/use-fetched';
import { RULE } from 'constants/notifications';
import BrowserNotificationBanner from '$web/component/browserNotificationBanner';

type Props = {
  notifications: Array<Notification>,
  notificationsFiltered: Array<Notification>,
  notificationCategories: Array<NotificationCategory>,
  fetching: boolean,
  unreadCount: number,
  unseenCount: number,
  doSeeAllNotifications: () => void,
  doReadNotifications: () => void,
  doNotificationList: (?Array<string>, ?boolean) => void,
  doNotificationCategories: () => void,
  activeChannel: ?ChannelClaim,
  doCommentReactList: (Array<string>) => Promise<any>,
};

export default function NotificationsPage(props: Props) {
  const {
    notifications,
    notificationsFiltered,
    fetching,
    unreadCount,
    unseenCount,
    doSeeAllNotifications,
    doReadNotifications,
    doNotificationList,
    doNotificationCategories,
    notificationCategories,
    activeChannel,
    doCommentReactList,
  } = props;
  const [name, setName] = usePersistedState('notifications--rule', NOTIFICATIONS.NOTIFICATION_NAME_ALL);
  const isFiltered = name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL;
  const list = isFiltered ? notificationsFiltered : notifications;

  const fetchedOnce = useFetched(fetching);
  const categoriesReady = notificationCategories;
  const notificationsReady = !isFiltered || fetchedOnce;
  const ready = categoriesReady && notificationsReady;

  // Fetch reacts
  React.useEffect(() => {
    if (ready && !fetching && activeChannel) {
      let idsForReactionFetch = [];
      list.map((notification) => {
        const { notification_rule, notification_parameters } = notification;
        const isComment =
          notification_rule === RULE.COMMENT ||
          notification_rule === RULE.COMMENT_REPLY ||
          notification_rule === RULE.CREATOR_COMMENT;
        const commentId =
          isComment &&
          notification_parameters &&
          notification_parameters.dynamic &&
          notification_parameters.dynamic.hash;

        if (commentId) {
          idsForReactionFetch.push(commentId);
        }
      });

      if (idsForReactionFetch.length !== 0) {
        doCommentReactList(idsForReactionFetch);
      }
    }
  }, [ready, doCommentReactList, list, activeChannel, fetching]);

  // Mark all as seen
  React.useEffect(() => {
    if (unseenCount > 0) {
      doSeeAllNotifications();
    }
  }, [unseenCount, doSeeAllNotifications]);

  const stringifiedNotificationCategories = notificationCategories ? JSON.stringify(notificationCategories) : '';

  // Fetch filtered notifications
  React.useEffect(() => {
    if (stringifiedNotificationCategories) {
      const arrayNotificationCategories = JSON.parse(stringifiedNotificationCategories);

      if (name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL) {
        try {
          const matchingCategory = arrayNotificationCategories.find((category) => category.name === name);
          if (matchingCategory) {
            doNotificationList(matchingCategory.types, false);
          }
        } catch (e) {
          console.error(e); // eslint-disable-line no-console
        }
      }
    }
  }, [name, notifications, stringifiedNotificationCategories, doNotificationList]);

  React.useEffect(() => {
    if (!notificationCategories) {
      doNotificationCategories();
    }
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Page className="notification-page">
      <BrowserNotificationBanner />

      {ready && (
        <div className="claim-list__header">
          <h1 className="card__title">{__('Notifications')}</h1>
          <div className="claim-list__alt-controls--wrap">
            {fetching && <Spinner type="small" delayed />}

            {unreadCount > 0 && (
              <Button
                icon={ICONS.EYE}
                onClick={doReadNotifications}
                button="secondary"
                label={__('Mark all as read')}
              />
            )}

            {notificationCategories && (
              <FormField type="select" name="filter" value={name} onChange={(e) => setName(e.target.value)}>
                {notificationCategories.map((category) => {
                  return (
                    <option key={category.name} value={category.name}>
                      {__(category.name)}
                    </option>
                  );
                })}
              </FormField>
            )}
          </div>
        </div>
      )}

      {!ready ? (
        <div className="main--empty">
          <Spinner />
        </div>
      ) : list && list.length > 0 && !(isFiltered && fetching) ? (
        <div className="card">
          <div className="notification_list">
            {list.map((notification) => {
              return <Notification key={notification.id} notification={notification} />;
            })}
          </div>
        </div>
      ) : (
        <div className="main--empty">
          {!fetching && (
            <Yrbl
              title={__('No notifications')}
              subtitle={
                isFiltered
                  ? __('Try selecting another filter.')
                  : __("You don't have any notifications yet, but they will be here when you do!")
              }
              actions={
                <div className="section__actions">
                  <Button button="primary" icon={ICONS.HOME} label={__('Go Home')} navigate="/" />
                </div>
              }
            />
          )}
        </div>
      )}
    </Page>
  );
}