/*
 This file is part of GNU Taler
 (C) 2022 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 
 */
import {
  HttpStatusCode,
  Logger,
  parseWithdrawUri,
  stringifyWithdrawUri,
} from "@gnu-taler/taler-util";
import {
  ErrorType,
  HttpResponse,
  HttpResponsePaginated,
  useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { Loading } from "../components/Loading.js";
import { useBackendContext } from "../context/backend.js";
import { getInitialBackendBaseURL } from "../hooks/backend.js";
import { notifyError, notifyInfo } from "../hooks/notification.js";
import { useSettings } from "../hooks/settings.js";
import { AccountPage } from "./AccountPage.js";
import { AdminPage } from "./AdminPage.js";
import { LoginForm } from "./LoginForm.js";
import { WithdrawalQRCode } from "./WithdrawalQRCode.js";
const logger = new Logger("AccountPage");
/**
 * show content based on state:
 * - LoginForm if the user is not logged in
 * - qr code if withdrawal in progress
 * - else account information
 * Use the handler to catch error cases
 *
 * @param param0
 * @returns
 */
export function HomePage({
  onRegister,
  onPendingOperationFound,
}: {
  onPendingOperationFound: (id: string) => void;
  onRegister: () => void;
}): VNode {
  const backend = useBackendContext();
  const [settings] = useSettings();
  const { i18n } = useTranslationContext();
  if (backend.state.status === "loggedOut") {
    return ;
  }
  if (settings.currentWithdrawalOperationId) {
    onPendingOperationFound(settings.currentWithdrawalOperationId);
    return ;
  }
  if (backend.state.isUserAdministrator) {
    return ;
  }
  return (
    
  );
}
export function WithdrawalOperationPage({
  operationId,
  onLoadNotOk,
  onAbort,
}: {
  operationId: string;
  onLoadNotOk: () => void;
  onAbort: () => void;
}): VNode {
  //FIXME: libeufin sandbox should return show to create the integration api endpoint
  //or return withdrawal uri from response
  const uri = stringifyWithdrawUri({
    bankIntegrationApiBaseUrl: `${getInitialBackendBaseURL()}/integration-api`,
    withdrawalOperationId: operationId,
  });
  const parsedUri = parseWithdrawUri(uri);
  const { i18n } = useTranslationContext();
  const [settings, updateSettings] = useSettings();
  function clearCurrentWithdrawal(): void {
    updateSettings("currentWithdrawalOperationId", undefined);
    onAbort();
  }
  if (!parsedUri) {
    notifyError({
      title: i18n.str`The Withdrawal URI is not valid: "${uri}"`,
    });
    return ;
  }
  return (
     {
        notifyInfo(i18n.str`Withdrawal confirmed!`);
      }}
      onAborted={clearCurrentWithdrawal}
      onLoadNotOk={onLoadNotOk}
    />
  );
}
export function handleNotOkResult(
  i18n: ReturnType["i18n"],
  onRegister?: () => void,
): (
  result:
    | HttpResponsePaginated
    | HttpResponse,
) => VNode {
  return function handleNotOkResult2(
    result:
      | HttpResponsePaginated
      | HttpResponse,
  ): VNode {
    if (result.loading) return ;
    if (!result.ok) {
      switch (result.type) {
        case ErrorType.TIMEOUT: {
          notifyError({
            title: i18n.str`Request timeout, try again later.`,
          });
          break;
        }
        case ErrorType.CLIENT: {
          if (result.status === HttpStatusCode.Unauthorized) {
            notifyError({
              title: i18n.str`Wrong credentials`,
            });
            return ;
          }
          const errorData = result.payload;
          notifyError({
            title: i18n.str`Could not load due to a client error`,
            description: errorData.error.description,
            debug: JSON.stringify(result),
          });
          break;
        }
        case ErrorType.SERVER: {
          notifyError({
            title: i18n.str`Server returned with error`,
            description: result.payload.error.description,
            debug: JSON.stringify(result.payload),
          });
          break;
        }
        case ErrorType.UNREADABLE: {
          notifyError({
            title: i18n.str`Unexpected error.`,
            description: `Response from ${result.info?.url} is unreadable, http status: ${result.status}`,
            debug: JSON.stringify(result),
          });
          break;
        }
        case ErrorType.UNEXPECTED: {
          notifyError({
            title: i18n.str`Unexpected error.`,
            description: `Diagnostic from ${result.info?.url} is "${result.message}"`,
            debug: JSON.stringify(result),
          });
          break;
        }
        default: {
          assertUnreachable(result);
        }
      }
      return error
;
    }
    return ;
  };
}
export function assertUnreachable(x: never): never {
  throw new Error("Didn't expect to get here");
}