import { getContextValueName, useHost, useLocale, useParentQuery, useParentState, useUserIdentity, } from "@saasquatch/component-boilerplate";
import { useEffect, useMemo } from "@saasquatch/universal-hooks";
import { getCountryObj } from "../utils";
import { COUNTRIES_NAMESPACE, COUNTRIES_QUERY_NAMESPACE, CURRENCIES_NAMESPACE, CURRENCIES_QUERY_NAMESPACE, FINANCE_NETWORK_SETTINGS_NAMESPACE, GET_COUNTRIES, GET_CURRENCIES, GET_FINANCE_NETWORK_SETTINGS, GET_USER, SORTED_COUNTRIES_NAMESPACE, TAX_CONTEXT_NAMESPACE, TAX_FORM_CONTEXT_NAMESPACE, USER_FORM_CONTEXT_NAMESPACE, USER_QUERY_NAMESPACE, } from "../data";
function getCurrentStep(user) {
  var _a, _b;
  if (!((_a = user.impactConnection) === null || _a === void 0 ? void 0 : _a.connected) || !((_b = user.impactConnection) === null || _b === void 0 ? void 0 : _b.publisher)) {
    return "/1";
  }
  const { requiredTaxDocumentType, currentTaxDocument, withdrawalSettings, brandedSignup, payoutsAccount, } = user.impactConnection.publisher;
  // If they do have a required document, look at current document
  if (requiredTaxDocumentType && !currentTaxDocument) {
    // Specific to custom CASH setting,
    if (payoutsAccount.hold &&
      payoutsAccount.holdReasons.includes("NO_W9_DOCUMENT"))
      return "/dashboard";
    return "/3";
  }
  if (!withdrawalSettings && brandedSignup)
    return "/4";
  return "/dashboard";
}
export function useTaxAndCash() {
  var _a, _b, _c, _d, _e;
  const host = useHost();
  const user = useUserIdentity();
  const locale = useLocale();
  // State for current step of form
  const [step, setStep] = useParentState({
    namespace: TAX_CONTEXT_NAMESPACE,
    initialValue: "/loading",
  });
  // State for when to hide steps, or override certain actions
  const [context, _setContext] = useParentState({
    namespace: TAX_FORM_CONTEXT_NAMESPACE,
    initialValue: {},
  });
  // State to carry user form information into step 2
  const [userFormContext, _setUserFormContext] = useParentState({
    namespace: USER_FORM_CONTEXT_NAMESPACE,
    initialValue: {
      firstName: undefined,
      lastName: undefined,
      email: undefined,
      countryCode: undefined,
      currency: undefined,
    },
  });
  const [_currenciesContext, setCurrenciesContext] = useParentState({
    namespace: CURRENCIES_NAMESPACE,
    initialValue: [],
  });
  const [_countriesContext, _setCountriesContext] = useParentState({
    namespace: COUNTRIES_NAMESPACE,
    initialValue: [],
  });
  const [_sortedCountriesContext, setSortedCountriesContext] = useParentState({
    namespace: SORTED_COUNTRIES_NAMESPACE,
    initialValue: [],
  });
  const { data, errors } = useParentQuery({
    namespace: USER_QUERY_NAMESPACE,
    query: GET_USER,
    skip: !user,
    options: {
      batch: false,
    },
  });
  const countryCode = ((_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.impactConnection) === null || _b === void 0 ? void 0 : _b.publisher) === null || _c === void 0 ? void 0 : _c.countryCode) ||
    userFormContext.countryCode;
  useParentQuery({
    namespace: COUNTRIES_QUERY_NAMESPACE,
    query: GET_COUNTRIES,
    skip: !user,
  });
  const { data: financeNetworkData, refetch } = useParentQuery({
    namespace: FINANCE_NETWORK_SETTINGS_NAMESPACE,
    query: GET_FINANCE_NETWORK_SETTINGS,
    skip: !user,
    variables: {
      filter: getFinanceNetworkFilter(),
    },
  });
  const { data: currenciesData } = useParentQuery({
    namespace: CURRENCIES_QUERY_NAMESPACE,
    query: GET_CURRENCIES,
    skip: !user,
    variables: {
      locale,
    },
  });
  const supportedCurrencies = useMemo(() => {
    var _a, _b;
    // Filter out any currencies not supported by finance network settings
    const allValidCurrencies = (_b = (_a = financeNetworkData === null || financeNetworkData === void 0 ? void 0 : financeNetworkData.impactFinanceNetworkSettings) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.reduce((agg, settings) => {
      var _a, _b;
      const currency = (_b = (_a = currenciesData === null || currenciesData === void 0 ? void 0 : currenciesData.currencies) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.find((currency) => currency.currencyCode === settings.currency);
      // Currency not in supported list
      if (!currency)
        return agg;
      // Currency already added to list
      if (agg.find((currency) => currency.currencyCode === settings.currency))
        return agg;
      // Currency not supported by selected country
      if (userFormContext.countryCode &&
        settings.countryCode !== countryCode)
        return agg;
      return [...agg, currency];
    }, []);
    return allValidCurrencies;
  }, [financeNetworkData, countryCode]);
  const intlLocale = (locale === null || locale === void 0 ? void 0 : locale.replace("_", "-")) || "en";
  const sortByName = (a, b) => a.displayName < b.displayName ? -1 : 1;
  const paymentOptions = (_d = financeNetworkData === null || financeNetworkData === void 0 ? void 0 : financeNetworkData.impactFinanceNetworkSettings) === null || _d === void 0 ? void 0 : _d.data;
  // filter out any duplicate countries and null countryCode
  const availableCountries = useMemo(() => new Set(paymentOptions === null || paymentOptions === void 0 ? void 0 : paymentOptions.map((option) => option.countryCode).filter((value) => value)), [paymentOptions]);
  const _topCountries = ["CA", "GB", "US"];
  const sortedCountries = useMemo(() => Array.from(availableCountries)
    .map((countryCode) => getCountryObj({ countryCode, locale: intlLocale }))
    .sort(sortByName)
    .reduce((prev, countryObj) => {
    if (_topCountries.includes(countryObj.countryCode))
      return [countryObj, ...prev];
    return [...prev, countryObj];
  }, []), [availableCountries]);
  useEffect(() => {
    if (sortedCountries)
      setSortedCountriesContext(sortedCountries);
  }, [sortedCountries]);
  useEffect(() => {
    if (supportedCurrencies)
      setCurrenciesContext(supportedCurrencies);
  }, [supportedCurrencies]);
  useEffect(() => {
    if (errors) {
      setStep("/error");
      return;
    }
    if (!host || !user)
      return;
    if (data) {
      const user = data === null || data === void 0 ? void 0 : data.user;
      if (!user || step !== "/loading")
        return;
      const currentStep = getCurrentStep(user);
      setStep(currentStep);
    }
  }, [host, user, (_e = data === null || data === void 0 ? void 0 : data.user) === null || _e === void 0 ? void 0 : _e.email, errors]);
  function getFinanceNetworkFilter() {
    var _a, _b, _c;
    if (step === "/1")
      return {};
    if (step === "/4")
      return { currency_eq: (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.impactConnection) === null || _b === void 0 ? void 0 : _b.publisher) === null || _c === void 0 ? void 0 : _c.currency };
    if (countryCode)
      return {
        countryCode_eq: countryCode,
      };
    return {};
  }
  return {
    step,
    setStep,
    context,
    namespace: getContextValueName(TAX_CONTEXT_NAMESPACE),
    loading: step === "/loading",
  };
}
