/*
 This file is part of GNU Taler
 (C) 2021-2023 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 { HttpStatusCode, LibtoolVersion } from "@gnu-taler/taler-util";
import {
  ErrorType,
  TranslationProvider,
  useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useMemo } from "preact/hooks";
import { ApplicationReadyRoutes } from "./ApplicationReadyRoutes.js";
import { Loading } from "./components/exception/loading.js";
import {
  NotConnectedAppMenu,
  NotificationCard
} from "./components/menu/index.js";
import {
  BackendContextProvider
} from "./context/backend.js";
import { ConfigContextProvider } from "./context/config.js";
import { useBackendConfig } from "./hooks/backend.js";
import { strings } from "./i18n/strings.js";

export function Application(): VNode {
  return (
    <BackendContextProvider>
      <TranslationProvider source={strings}>
        <ApplicationStatusRoutes />
      </TranslationProvider>
    </BackendContextProvider>
  );
}

/**
 * Check connection testing against /config
 * 
 * @returns 
 */
function ApplicationStatusRoutes(): VNode {
  const result = useBackendConfig();
  const { i18n } = useTranslationContext();

  const configData = result.ok && result.data
    ? result.data
    : undefined;
  const ctx = useMemo(() => (configData), [configData]);

  if (!result.ok) {
    if (result.loading) return <Loading />;
    if (
      result.type === ErrorType.CLIENT &&
      result.status === HttpStatusCode.Unauthorized
    ) {
      return (
        <Fragment>
          <NotConnectedAppMenu title="Login" />
          <NotificationCard
            notification={{
              message: i18n.str`Checking the /config endpoint got authorization error`,
              type: "ERROR",
              description: `The /config endpoint of the backend server should be accesible`,
            }}
          />
        </Fragment>
      );
    }
    if (
      result.type === ErrorType.CLIENT &&
      result.status === HttpStatusCode.NotFound
    ) {
      return (
        <Fragment>
          <NotConnectedAppMenu title="Error" />
          <NotificationCard
            notification={{
              message: i18n.str`Could not find /config endpoint on this URL`,
              type: "ERROR",
              description: `Check the URL or contact the system administrator.`,
            }}
          />
        </Fragment>
      );
    }
    if (result.type === ErrorType.SERVER) {
      <Fragment>
        <NotConnectedAppMenu title="Error" />
        <NotificationCard
          notification={{
            message: i18n.str`Server response with an error code`,
            type: "ERROR",
            description: i18n.str`Got message "${result.message}" from ${result.info?.url}`,
          }}
        />
      </Fragment>;
    }
    if (result.type === ErrorType.UNREADABLE) {
      <Fragment>
        <NotConnectedAppMenu title="Error" />
        <NotificationCard
          notification={{
            message: i18n.str`Response from server is unreadable, http status: ${result.status}`,
            type: "ERROR",
            description: i18n.str`Got message "${result.message}" from ${result.info?.url}`,
          }}
        />
      </Fragment>;
    }
    return (
      <Fragment>
        <NotConnectedAppMenu title="Error" />
        <NotificationCard
          notification={{
            message: i18n.str`Unexpected Error`,
            type: "ERROR",
            description: i18n.str`Got message "${result.message}" from ${result.info?.url}`,
          }}
        />
      </Fragment>
    );
  }

  const SUPPORTED_VERSION = "8:1:4"
  if (result.data && !LibtoolVersion.compare(
    SUPPORTED_VERSION,
    result.data.version,
  )?.compatible) {
    return <Fragment>
      <NotConnectedAppMenu title="Error" />
      <NotificationCard
        notification={{
          message: i18n.str`Incompatible version`,
          type: "ERROR",
          description: i18n.str`Merchant backend server version ${result.data.version} is not compatible with the supported version ${SUPPORTED_VERSION}`,
        }}
      />
    </Fragment>
  }

  return (
    <div class="has-navbar-fixed-top">
      <ConfigContextProvider value={ctx!}>
        <ApplicationReadyRoutes />
      </ConfigContextProvider>
    </div>
  );
}
