import { useEngagementMedium, useMutation, useProgramId, useQuery, useUserIdentity, } from "@saasquatch/component-boilerplate";
import { useEffect, useRef, useState } from "@saasquatch/universal-hooks";
import { gql } from "graphql-request";
import { intl } from "../../global/global";
const FuelTankRewardsQuery = gql `
  query fuelTankRewardsQuery($programId: ID!) {
    user: viewer {
      ... on User {
        instantAccessRewards(
          filter: { type_eq: FUELTANK, programId_eq: $programId }
        ) {
          data {
            fuelTankCode
            fuelTankType
            statuses
            dateGiven
            dateExpires
            dateRedeemed
            dateCancelled
            dateScheduledFor
            datePendingForUnhandledError
            pendingReasons
          }
          count
          totalCount
        }
      }
    }
  }
`;
const WIDGET_ENGAGEMENT_EVENT = gql `
  mutation loadEvent($eventMeta: UserAnalyticsEvent!) {
    createUserAnalyticsEvent(eventMeta: $eventMeta)
  }
`;
export function useCouponCode(props) {
  var _a, _b, _c;
  const user = useUserIdentity();
  const programId = useProgramId();
  const engagementMedium = useEngagementMedium();
  const [sendLoadEvent] = useMutation(WIDGET_ENGAGEMENT_EVENT);
  const [retried, setRetried] = useState(false);
  const [countdown, setCountdown] = useState(60);
  const timerRef = useRef(undefined);
  const countdownRef = useRef(undefined);
  const { data, loading, refetch, errors } = useQuery(FuelTankRewardsQuery, { programId }, !(user === null || user === void 0 ? void 0 : user.jwt));
  async function checkReward() {
    var _a, _b, _c, _d, _e, _f;
    const data = await refetch();
    setRetried(true);
    if (!((_f = (_e = (_d = (_c = (_b = (_a = data) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.instantAccessRewards) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.pendingReasons) === null || _f === void 0 ? void 0 : _f.includes("ERROR_SYNCING_FUEL_TANK_CODE"))) {
      return clearInterval(timerRef.current);
    }
  }
  const reward = (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.instantAccessRewards) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c[0];
  const startTimer = (countdown = 61000) => setInterval(checkReward, countdown);
  const startCountdown = (countdown) => setInterval(() => setCountdown(countdown), 1000);
  // Refetch reward status timer
  useEffect(() => {
    var _a, _b;
    if (!timerRef.current && ((_a = reward === null || reward === void 0 ? void 0 : reward.statuses) === null || _a === void 0 ? void 0 : _a.includes("PENDING")) && ((_b = reward === null || reward === void 0 ? void 0 : reward.pendingReasons) === null || _b === void 0 ? void 0 : _b.includes("ERROR_SYNCING_FUEL_TANK_CODE"))) {
      timerRef.current = startTimer();
    }
    return () => {
      clearInterval(timerRef.current);
    };
  }, []);
  // Countdown timer
  useEffect(() => {
    var _a, _b;
    if (countdown > 0 && ((_a = reward === null || reward === void 0 ? void 0 : reward.statuses) === null || _a === void 0 ? void 0 : _a.includes("PENDING")) && ((_b = reward === null || reward === void 0 ? void 0 : reward.pendingReasons) === null || _b === void 0 ? void 0 : _b.includes("ERROR_SYNCING_FUEL_TANK_CODE"))) {
      clearInterval(countdownRef.current);
      countdownRef.current = startCountdown(countdown - 1);
    }
    return () => {
      clearInterval(countdownRef.current);
    };
  }, [countdown, reward]);
  useEffect(() => {
    var _a, _b;
    // Retry after a minute if the reward is pending and has an error syncing the fuel tank code
    if (((_a = reward === null || reward === void 0 ? void 0 : reward.statuses) === null || _a === void 0 ? void 0 : _a.includes("PENDING")) && ((_b = reward === null || reward === void 0 ? void 0 : reward.pendingReasons) === null || _b === void 0 ? void 0 : _b.includes("ERROR_SYNCING_FUEL_TANK_CODE"))) {
      startTimer();
    }
  }, [reward]);
  const getStatus = (reward) => {
    if (!reward || !reward.statuses)
      return "ERROR";
    const state = reward.statuses[reward.statuses.length - 1];
    if (state === "PENDING" &&
      reward.pendingReasons.includes("ERROR_SYNCING_FUEL_TANK_CODE"))
      return "ERROR_SYNCING_FUEL_TANK_CODE";
    if (state === "PENDING" && reward.dateScheduledFor === null)
      return "EMPTY_TANK";
    return state;
  };
  const rewardStatus = getStatus(reward);
  const dateAvailable = rewardStatus === "PENDING" && reward.dateScheduledFor
    ? new Date(reward.dateScheduledFor).toLocaleDateString("default", {
      day: "numeric",
      month: "long",
      year: "numeric",
    })
    : undefined;
  const copyString = (reward === null || reward === void 0 ? void 0 : reward.fuelTankCode) || "...";
  const [open, setOpen] = useState(false);
  function onClick() {
    // Should well supported: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard#browser_compatibility
    // Only if called from a user-initiated event
    navigator.clipboard.writeText(copyString);
    setOpen(true);
    setTimeout(() => setOpen(false), props.tooltiplifespan);
    sendLoadEvent({
      eventMeta: {
        programId,
        id: user === null || user === void 0 ? void 0 : user.id,
        accountId: user === null || user === void 0 ? void 0 : user.accountId,
        type: "USER_REFERRAL_PROGRAM_ENGAGEMENT_EVENT",
        meta: {
          engagementMedium,
          shareMedium: "DIRECT",
        },
      },
    });
  }
  const getRewardStatusText = (status) => {
    switch (status) {
      case "CANCELLED":
        return props.cancelledErrorText;
      case "EXPIRED":
        return props.expiredErrorText;
      case "EMPTY_TANK":
        return props.fullfillmentErrorText;
      case "ERROR_SYNCING_FUEL_TANK_CODE":
        return retried
          ? intl.formatMessage({
            id: "codeSyncErrorText",
            defaultMessage: props.codeSyncErrorText,
          }, {
            supportEmail: "advocate-support@impact.com",
          })
          : intl.formatMessage({
            id: "codeSyncErrorText",
            defaultMessage: props.codeSyncErrorRetryText,
          }, {
            supportEmail: "advocate-support@impact.com",
            timeRemaining: countdown,
          });
      case "PENDING":
        return props.pendingErrorText.replace("{unpendDate}", dateAvailable);
      case "REDEEMED":
        return props.redeemedErrorText;
      case "AVAILABLE":
        return "";
      default:
        return props.genericErrorText;
    }
  };
  const getRewardStatusErrorType = (status) => {
    switch (status) {
      case "EXPIRED":
      case "EMPTY_TANK":
      case "CANCELLED":
      case "ERROR":
      case "ERROR_SYNCING_FUEL_TANK_CODE":
        return "warning";
      case "PENDING":
        return "info";
      case "REDEEMED":
        return "success";
      default:
        return;
    }
  };
  const errorText = getRewardStatusText(rewardStatus);
  const errorType = getRewardStatusErrorType(rewardStatus);
  const error = rewardStatus !== "AVAILABLE";
  return {
    ...props,
    onClick,
    open,
    copyString,
    error,
    errorText,
    dateAvailable,
    loading,
    errorType,
    buttonType: props.buttonType || "primary",
  };
}
