import Failure from "core/failure";
import React from "react";
import { useTranslation } from "react-i18next";
import { Service } from "services/domain/serviceEntity";
import { SubscriptionsStore } from "subscriptions/domain/subscriptionsStore";
import { forkToServiceUseCase } from "subscriptions/useCases/forkToServiceUseCase";
import { getSubscriptionsUseCase } from "subscriptions/useCases/getSubscriptions";
import { serviceSubscribeUseCase } from "subscriptions/useCases/serviceSubscribeUseCase";
import { UIStore } from "ui/domain/uiStore";

function useSubscriptionsViewModel(
  store: SubscriptionsStore,
  notifications: UIStore
) {
  const { isLoading, isFailed, subscribing, subscriptions } = store;

  const { t } = useTranslation();

  const loadSubscriptions = React.useCallback(() => {
    return getSubscriptionsUseCase({
      get: store.get,
    });
  }, [store.get]);

  React.useEffect(() => {
    loadSubscriptions();
  }, [loadSubscriptions]);

  const hasSubscription = React.useCallback(
    (id: Service["id"]) => store.subscriptions?.includes(id) ?? false,
    [store.subscriptions]
  );

  const processingSubscription = React.useCallback(
    (id: Service["id"]) => store.subscribing?.includes(id) ?? false,
    [store.subscribing]
  );

  const subscribe = React.useCallback(
    (id: Service["id"], password: string) => {
      return serviceSubscribeUseCase(
        {
          subscribe: store.subscribe,
          subscriptions: store.subscriptions,
        },
        id,
        password
      )
        ?.then(() => {
          notifications.notify({
            body: t("subscriptions.subscribed"),
            status: "success",
            title: "Success",
          });
        })
        .catch((failure: any) => {
          if (!Failure.isFailure(failure)) {
            return Promise.reject(failure);
          }

          notifications.notify({
            body: failure.key ? t(failure.key) : failure.message,
            status: "error",
            title: t("failures.subscriptions.failure"),
          });

          return Promise.reject(failure);
        });
    },
    [store.subscribe, store.subscriptions, t, notifications]
  );

  const forkTo = React.useCallback(
    (id: Service["id"], href: string) => {
      return forkToServiceUseCase(
        {
          forkTo: store.forkTo,
        },
        id
      ).then(() => {
        window.open(href);
      }).catch((failure) => {
        if (!Failure.isFailure(failure)) {
          return Promise.reject(failure);
        }
        notifications.notify({
          body: failure.key ? t(failure.key) : failure.message,
          status: "error",
          title: t("failures.subscriptions.failure"),
        });
      });
    },
    [store.forkTo, notifications, t]
  );

  return {
    /* --------------------------------- States --------------------------------- */
    subscriptions,
    subscribing,
    isLoading,
    isFailed,
    /* ---------------------------------- Utils --------------------------------- */
    hasSubscription,
    processingSubscription,
    /* --------------------------------- Actions -------------------------------- */
    loadSubscriptions,
    subscribe,
    forkTo,
  };
}

export { useSubscriptionsViewModel };
