'use strict';

const index = require('./index-8277cbb3.js');
const domContextHooks_module = require('./dom-context-hooks.module-e7b6727c.js');
const index_module = require('./index.module-f8c8495f.js');
const reRender = require('./re-render-72a0ef45.js');
const useChildElements = require('./useChildElements-041127d7.js');

const debug = domContextHooks_module.browser("sq:useReferralTable");
const CSS_NAMESPACE = "sqm-referral-table";
const GET_REFERRER_DATA = index_module.dist.gql `
  query getReferrals(
    $programId: ID
    $rewardFilter: RewardFilterInput
    $locale: RSLocale
  ) {
    viewer {
      ... on User {
        referredByReferral(programId: $programId) {
          dateConverted
          dateFraudChecksCompleted
          dateModerated
          dateModified
          dateReferralEnded
          dateReferralPaid
          dateReferralStarted
          dateUserModified
          referrerUser {
            firstName
            lastName
          }
          rewards(filter: $rewardFilter) {
            id
            type
            value
            unit
            name
            dateGiven
            dateExpires
            dateCancelled
            dateRedeemed
            dateScheduledFor
            fuelTankCode
            fuelTankType
            currency
            prettyValue(locale: $locale)
            statuses
            globalRewardKey
            programRewardKey
            partnerFundsTransfer {
              id
              status
              dateScheduled
              dateCreated
              dateTransferred
            }
            meta {
              status
              integration {
                name
              }
              message
              customMeta
            }
            rewardRedemptionTransactions {
              data {
                exchangedRewards {
                  data {
                    prettyValue(locale: $locale)
                    type
                    fuelTankCode
                    globalRewardKey
                  }
                }
              }
            }
          }
        }
      }
    }
  }
`;
const GET_REFERRAL_DATA = index_module.dist.gql `
  query getReferrals(
    $limit: Int!
    $offset: Int!
    $referralFilter: ReferralFilterInput
    $rewardFilter: RewardFilterInput
    $locale: RSLocale
  ) {
    viewer {
      ... on User {
        id
        paidReferrals: referrals(
          filter: { dateReferralPaid_timeframe: "this_10_years" }
          limit: 1
        ) {
          totalCount
        }
        referrals(limit: $limit, offset: $offset, filter: $referralFilter) {
          totalCount
          count
          data {
            id
            referredUser {
              id
              accountId
              firstName
              lastName
              email
              programGoals {
                goalId
                programId
                count
                firstDate
                lastDate
                conversionCount
              }
            }
            shareLinkUsed
            referralCodeUsed
            moderationStatus
            dateConverted
            dateFraudChecksCompleted
            dateModerated
            dateModified
            dateReferralEnded
            dateReferralPaid
            dateReferralStarted
            dateUserModified
            programId
            program {
              id
              name
            }
            fraudData {
              autoModerationStatus
              manualModerationStatus
              moderationStatus
            }
            rewards(filter: $rewardFilter) {
              id
              type
              value
              unit
              name
              dateGiven
              dateExpires
              dateCancelled
              dateRedeemed
              dateScheduledFor
              fuelTankCode
              fuelTankType
              currency
              prettyValue(locale: $locale)
              pendingReasons
              statuses
              globalRewardKey
              programRewardKey
              partnerFundsTransfer {
                id
                status
                dateScheduled
                dateCreated
                dateTransferred
              }
              referral {
                dateModerated
                fraudData {
                  autoModerationStatus
                  manualModerationStatus
                  moderationStatus
                }
              }
              meta {
                status
                integration {
                  name
                }
                message
                customMeta
              }
              rewardRedemptionTransactions {
                data {
                  exchangedRewards {
                    data {
                      prettyValue(locale: $locale)
                      type
                      fuelTankCode
                      globalRewardKey
                    }
                  }
                }
              }
            }
            childNodes(limit: 10, offset: 0) {
              data {
                data {
                  id
                  ... on FlatReward {
                    id
                    statuses
                    type
                    value
                  }
                  ... on ProgramEmailTransaction {
                    id
                    rewardId
                    dateCreated
                    dateSent
                    dateQueued
                  }
                }
                depth
              }
            }
          }
        }
      }
    }
  }
`;
const GET_IMPACT_TAX = index_module.dist.gql `
  query getImpactTax {
    viewer {
      ... on User {
        id
        impactConnection {
          connected
          taxHandlingEnabled
          publisher {
            requiredTaxDocumentType
            currentTaxDocument {
              status
              type
              dateCreated
            }
            withdrawalSettings {
              paymentMethod
            }
            payoutsAccount {
              hold
              holdReasons
              balance
            }
          }
        }
      }
    }
  }
`;
function useReferralTable(props, emptyElement, loadingElement) {
  var _a, _b, _c, _d;
  const user = index_module.J();
  const programIdContext = index_module.H();
  // Default to context, overriden by props
  const resolvedProgramId = (_a = props.programId) !== null && _a !== void 0 ? _a : programIdContext;
  const programId = resolvedProgramId === "GLOBAL" ? null : resolvedProgramId;
  // If no program ID, shows all programs
  const referralFilter = programId
    ? programId === "classic"
      ? { programId_exists: false }
      : { programId_eq: programId }
    : {};
  const rewardFilter = {
    userId_eq: user === null || user === void 0 ? void 0 : user.id,
    accountId_eq: user === null || user === void 0 ? void 0 : user.accountId,
  };
  const [content, setContent] = domContextHooks_module.useReducer((state, next) => ({
    ...state,
    ...next,
  }), {
    columns: [],
    rows: [],
    loading: false,
    page: 0,
  });
  const locale = index_module.L();
  const { data: referrerResponse, loading: referrerLoading, refetch, } = index_module.wn(GET_REFERRER_DATA, {
    programId: programId === "classic" ? null : programId,
    rewardFilter,
    locale,
  }, !props.showReferrer || !(user === null || user === void 0 ? void 0 : user.jwt));
  const referrerData = (_b = referrerResponse === null || referrerResponse === void 0 ? void 0 : referrerResponse.viewer) === null || _b === void 0 ? void 0 : _b.referredByReferral;
  const showReferrerRow = props.showReferrer && !!(referrerData === null || referrerData === void 0 ? void 0 : referrerData.dateReferralStarted);
  const { data: taxResponse, loading: taxLoading } = index_module.wn(GET_IMPACT_TAX, {}, !(user === null || user === void 0 ? void 0 : user.jwt));
  const taxConnection = (_c = taxResponse === null || taxResponse === void 0 ? void 0 : taxResponse.viewer) === null || _c === void 0 ? void 0 : _c.impactConnection;
  const { envelope: referralData, states, callbacks, } = index_module.Rn(GET_REFERRAL_DATA, (data) => { var _a; return (_a = data === null || data === void 0 ? void 0 : data.viewer) === null || _a === void 0 ? void 0 : _a.referrals; }, {
    limit: props.perPage,
    offset: 0,
  }, {
    referralFilter,
    rewardFilter,
    locale,
  }, (props.showReferrer && referrerLoading && !referrerResponse) || !(user === null || user === void 0 ? void 0 : user.jwt));
  domContextHooks_module.useEffect(() => {
    if (states.currentPage === 0 && showReferrerRow)
      callbacks.setLimit(props.perPage - 1);
  }, [showReferrerRow]);
  domContextHooks_module.useEffect(() => {
    if (props.showReferrer && showReferrerRow) {
      callbacks.setLimit(props.perPage - 1);
      callbacks.setCurrentPage(0);
    }
    else {
      callbacks.setLimit(props.perPage);
      callbacks.setCurrentPage(0);
    }
  }, [props.showReferrer]);
  const tick = reRender.useRerenderListener();
  const data = referralData === null || referralData === void 0 ? void 0 : referralData.data;
  const components = useChildElements.useChildElements();
  async function getComponentData(components) {
    // filter out loading and empty states from columns array
    const columnComponents = components.filter((component) => component.slot !== "loading" && component.slot !== "empty");
    // get the column titles (renderLabel is asynchronous)
    const columnsPromise = columnComponents === null || columnComponents === void 0 ? void 0 : columnComponents.map(async (c) => tryMethod(c, () => c.renderLabel()));
    // show the referrer row before any other rows
    let referrerRow;
    if (showReferrerRow && states.currentPage === 0) {
      const referrerPromise = columnComponents === null || columnComponents === void 0 ? void 0 : columnComponents.map(async (c) => tryMethod(c, () => c.renderReferrerCell(referrerData, locale, index.h)));
      referrerRow = await Promise.all(referrerPromise);
    }
    // get the column cells (renderCell is asynchronous)
    const cellsPromise = data === null || data === void 0 ? void 0 : data.map(async (r) => {
      const cellPromise = columnComponents === null || columnComponents === void 0 ? void 0 : columnComponents.map(async (c) => tryMethod(c, () => c.renderCell(r, { locale, taxConnection }, index.h)));
      const cells = (await Promise.all(cellPromise));
      return cells;
    });
    const rows = cellsPromise &&
      [referrerRow, ...(await Promise.all(cellsPromise))].filter((value) => value);
    setContent({ rows });
    const columns = columnsPromise && (await Promise.all(columnsPromise));
    // Set the content to render and finish loading components
    setContent({ columns, loading: false, page: states.currentPage });
  }
  domContextHooks_module.useEffect(() => {
    setContent({ loading: true });
    referralData && getComponentData(components);
  }, [referralData, components, tick]);
  const isEmpty = !((_d = content === null || content === void 0 ? void 0 : content.rows) === null || _d === void 0 ? void 0 : _d.length) && !(data === null || data === void 0 ? void 0 : data.length);
  const show = 
  // 1 - Loading if loading
  states.loading || content.loading || taxLoading
    ? "loading"
    : // 2 - Empty if empty
      isEmpty
        ? "empty"
        : // 3 - Then show rows
          "rows";
  return {
    states: {
      hasNext: states.currentPage < states.pageCount - 1,
      hasPrev: states.currentPage > 0,
      show,
      namespace: CSS_NAMESPACE,
    },
    data: {
      textOverrides: {
        showLabels: !props.hideLabels,
        prevLabel: props.prevLabel,
        moreLabel: props.moreLabel,
      },
      //   referralData: data,
      hiddenColumns: props.hiddenColumns,
      smBreakpoint: props.smBreakpoint,
      mdBreakpoint: props.mdBreakpoint,
    },
    elements: {
      columns: content.columns,
      rows: content.rows,
      emptyElement,
      loadingElement,
    },
    callbacks: {
      nextPage: () => {
        if (states.currentPage === 0 && showReferrerRow)
          callbacks.setLimit(props.perPage);
        callbacks.setCurrentPage(states.currentPage + 1);
      },
      prevPage: () => {
        if (states.currentPage === 1 && showReferrerRow)
          callbacks.setLimit(props.perPage - 1);
        callbacks.setCurrentPage(states.currentPage - 1);
      },
    },
  };
}
function generateUserError(e) {
  try {
    return JSON.stringify(e);
  }
  catch (e) {
    return "An unknown error";
  }
}
async function tryMethod(c, callback) {
  const tag = c.tagName.toLowerCase();
  await customElements.whenDefined(tag);
  let renderPromise;
  try {
    renderPromise = callback();
  }
  catch (e) {
    // renderLabel did not return a promise, so this method probably doesn't exist
    // therefore, we IGNORE the label
    if (callback.name === "renderReferrerCell") {
      debug("column does not have a renderReferrerCell method.");
    }
    else {
      debug("label promise failed", e);
    }
    debug("label promise failed", e);
    return index.h("span", null);
  }
  try {
    return await renderPromise;
  }
  catch (e) {
    // The column returned a promise, and that promise failed.
    // This should not happen so we fail fast
    debug("Error rendering label", e);
    const userError = generateUserError(e);
    return (index.h("details", null,
      index.h("summary", null, "Error"),
      userError));
  }
}

exports.generateUserError = generateUserError;
exports.tryMethod = tryMethod;
exports.useReferralTable = useReferralTable;
