/*
 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)
 * @author Nic Eigel
 */

import {HttpStatusCode, LibtoolVersion} from "@gnu-taler/taler-util";
import {
    ErrorType,
    TranslationProvider,
    useTranslationContext
} from "@gnu-taler/web-util/browser";
import {Fragment, VNode, h, render} 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 accessible`,
                        }}
                    />
                </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 = "1:0:1"
    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`Auditor 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>
    );
}