/*
 This file is part of GNU Taler
 (C) 2021-2024 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
/**
 *
 * @author Sebastian Javier Marchano (sebasjm)
 */

import { ChallengeResponse } from "@gnu-taler/taler-util";
import { useState } from "preact/hooks";
import { SafeHandlerTemplate } from "./useNotifications.js";

/**
 * State of the current MFA operation and handler to manage
 * the state and retry.
 *
 */
export interface MfaState {
  /**
   * If a mfa has been started this will contain
   * the challenge response.
   */
  pendingChallenge: ChallengeResponse | undefined;

  onChallengeRequired: (c: ChallengeResponse, repeat?: SafeHandlerTemplate<[ids:string[]], any>) => void;
  /**
   * Cancel the current pending challenge.
   *
   * @returns
   */
  doCancelChallenge: () => void;

  repeatCall?: SafeHandlerTemplate<[string[]], any>;
}

/**
 * Handler to be used by the function performing the MFA
 * guarded operation
 */
export interface MfaHandler {
  /**
   * Callback handler to use when the operation fails with MFA required
   * @param challenge
   * @param params
   * @returns
   */
  onChallengeRequired: (challenge: ChallengeResponse, ...params: any[]) => void;
  /**
   * Challenges that are already solved and can be used for the operation.
   * If this is undefined it may mean that it is the first call.
   */
  ids: string[] | undefined;
}

/**
 * asd
 */
type CallbackFactory<T extends any[], R> = (
  h: MfaHandler,
) => (...args: T) => Promise<R>;

/**
 * @returns
 */
export function useChallengeHandler(): MfaState {
  const [state, setState] = useState<{challenge: ChallengeResponse, repeat?: SafeHandlerTemplate<[string[]], any>}>();

  function reset() {
    setState(undefined);
  }

  function onChallengeRequired(challenge: ChallengeResponse, repeat?: SafeHandlerTemplate<[string[]], any>) {
    setState({challenge, repeat})
  }

  return {
    doCancelChallenge: reset,
    onChallengeRequired,
    pendingChallenge: state?.challenge,
    repeatCall: state?.repeat,
  };
}
