import { useMutation, useParent, useParentQueryValue, useParentValue, useUserIdentity, } from "@saasquatch/component-boilerplate";
import { useEffect, useState } from "@saasquatch/universal-hooks";
import { gql } from "graphql-request";
import { TAX_CONTEXT_NAMESPACE, TAX_FORM_CONTEXT_NAMESPACE, USER_QUERY_NAMESPACE, } from "../data";
import { TAX_FORM_UPDATED_EVENT_KEY } from "../eventKeys";
import { taxTypeToName, validTaxDocument } from "../utils";
const GET_TAX_DOCUMENT = gql `
  mutation createImpactPublisherTaxDocument(
    $vars: CreateImpactPublisherTaxDocumentInput!
  ) {
    createImpactPublisherTaxDocument(
      createImpactPublisherTaxDocumentInput: $vars
    ) {
      documentUrl
    }
  }
`;
const COMPLETE_TAX_DOCUMENT = gql `
  mutation completeImpactPublisherTaxDocument($vars: UserIdInput!) {
    completeImpactPublisherTaxDocument(user: $vars) {
      success
    }
  }
`;
export const DOCUSIGN_ERROR_STATES = [
  "exception",
  "decline",
  "cancel",
  "fax_pending",
];
export const DOCUSIGN_EXPIRED_STATES = ["ttl_expired", "session_timeout"];
export const DOCUSIGN_SUCCESS_STATES = ["signing_complete", "viewing_complete"];
export function useDocusignForm(props) {
  var _a, _b, _c;
  const user = useUserIdentity();
  const context = useParentValue(TAX_FORM_CONTEXT_NAMESPACE);
  const [step, setStep] = useParent(TAX_CONTEXT_NAMESPACE);
  const { data, loading: userLoading, refetch, } = useParentQueryValue(USER_QUERY_NAMESPACE);
  const publisher = (_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;
  const [createTaxDocument, { loading: documentLoading, data: document, errors: documentErrors },] = useMutation(GET_TAX_DOCUMENT);
  const [completeTaxDocument, { loading: completeDocumentLoading, data: completeData, errors: completeErrors, },] = useMutation(COMPLETE_TAX_DOCUMENT);
  const [docusignStatus, setDocusignStatus] = useState(undefined);
  const [participantType, setParticipantType] = useState(undefined);
  const [errors, setErrors] = useState({});
  const [loading, setLoading] = useState(false);
  const [showExitButton, setShowExitButton] = useState(false);
  const [showModal, setShowModal] = useState(true);
  // Only look at current document if it's valid (same as required type)
  const existingDocumentType = validTaxDocument(publisher === null || publisher === void 0 ? void 0 : publisher.requiredTaxDocumentType) && (publisher === null || publisher === void 0 ? void 0 : publisher.currentTaxDocument)
    ? publisher === null || publisher === void 0 ? void 0 : publisher.requiredTaxDocumentType : undefined;
  const actualDocumentType = existingDocumentType ||
    getDocumentType(participantType) || (publisher === null || publisher === void 0 ? void 0 : publisher.requiredTaxDocumentType);
  useEffect(() => {
    if (!existingDocumentType)
      return;
    if (existingDocumentType === "W8BEN") {
      setParticipantType("individualParticipant");
    }
    else if (existingDocumentType === "W8BENE") {
      setParticipantType("businessEntity");
    }
  }, [existingDocumentType]);
  useEffect(() => {
    // Skip if no publisher info
    if (!user || !publisher)
      return;
    const fetchDocument = async () => {
      try {
        const result = await createTaxDocument({
          vars: {
            provider: "COMPLY_EXCHANGE",
            user: {
              id: user.id,
              accountId: user.accountId,
            },
            ...(participantType
              ? { isBusinessEntity: participantType === "businessEntity" }
              : {}),
          },
        });
        if (!result || result.message)
          throw new Error();
      }
      catch (e) {
        setErrors({ docusign: true });
      }
    };
    fetchDocument();
  }, [user, publisher, participantType]);
  const completeDocument = async () => {
    if (!user)
      return;
    try {
      setLoading(true);
      const result = await completeTaxDocument({
        vars: {
          id: user.id,
          accountId: user.accountId,
        },
      });
      if (!result || result.message)
        throw new Error();
      // @ts-expect-error: no data type for result
      if (!result.completeImpactPublisherTaxDocument.success)
        throw new Error();
      // Fire form change event
      window.dispatchEvent(new Event(TAX_FORM_UPDATED_EVENT_KEY));
      setShowExitButton(true);
    }
    catch (e) {
      setErrors({ general: true });
    }
    finally {
      setLoading(false);
    }
  };
  const progressStep = () => {
    // return to dashboard
    if (window.location.hash) {
      window.location.hash = "";
    }
    else {
      setStep(context.overrideNextStep ||
        !!(publisher === null || publisher === void 0 ? void 0 : publisher.withdrawalSettings) ||
        !(publisher === null || publisher === void 0 ? void 0 : publisher.brandedSignup)
        ? "/dashboard"
        : "/4");
    }
  };
  const allLoading = userLoading || documentLoading || loading;
  return {
    states: {
      step: step === null || step === void 0 ? void 0 : step.replace("/", ""),
      hideSteps: context.hideSteps,
      disabled: allLoading,
      participantTypeDisabled: allLoading || !!existingDocumentType,
      loading: userLoading || loading || completeDocumentLoading,
      urlLoading: documentLoading,
      loadingError: !!(documentErrors === null || documentErrors === void 0 ? void 0 : documentErrors.message),
      formState: {
        participantType,
        taxFormExpired: DOCUSIGN_EXPIRED_STATES.includes(docusignStatus),
        errors,
      },
      docusignStatus,
      documentType: actualDocumentType,
      documentTypeString: taxTypeToName(actualDocumentType),
      showExitButton,
      showModal,
    },
    data: {
      taxForm: actualDocumentType,
      documentUrl: (_c = document === null || document === void 0 ? void 0 : document.createImpactPublisherTaxDocument) === null || _c === void 0 ? void 0 : _c.documentUrl,
    },
    callbacks: {
      setDocusignStatus,
      completeDocument,
      onExit: progressStep,
      setParticipantType,
      onModalClose: () => setShowModal(false),
      onModalOpen: () => setShowModal(true),
    },
    text: props.getTextProps(),
  };
}
function getDocumentType(p) {
  if (p === "businessEntity")
    return "W8BENE";
  if (p === "individualParticipant")
    return "W8BEN";
  else
    return undefined;
}
