/*
 This file is part of GNU Taler
 (C) 2022-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/>
 */

import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { createHashHistory } from "history";
import { Fragment, VNode, h } from "preact";
import { Route, Router, route } from "preact-router";
import { useEffect } from "preact/hooks";

import { useBackendState } from "./hooks/backend.js";
import { BankFrame } from "./pages/BankFrame.js";
import { WithdrawalOperationPage } from "./pages/WithdrawalOperationPage.js";
import { LoginForm } from "./pages/LoginForm.js";
import { PublicHistoriesPage } from "./pages/PublicHistoriesPage.js";
import { RegistrationPage } from "./pages/RegistrationPage.js";
import { AdminHome } from "./pages/admin/AdminHome.js";
import { CreateCashout } from "./pages/business/CreateCashout.js";
import { ShowAccountDetails } from "./pages/account/ShowAccountDetails.js";
import { UpdateAccountPassword } from "./pages/account/UpdateAccountPassword.js";
import { RemoveAccount } from "./pages/admin/RemoveAccount.js";
import { CreateNewAccount } from "./pages/admin/CreateNewAccount.js";
import { CashoutListForAccount } from "./pages/account/CashoutListForAccount.js";
import { ShowCashoutDetails } from "./pages/business/ShowCashoutDetails.js";
import { WireTransfer } from "./pages/WireTransfer.js";
import { AccountPage } from "./pages/AccountPage/index.js";
import { useSettingsContext } from "./context/settings.js";
import { useBankCoreApiContext } from "./context/config.js";
import { DownloadStats } from "./pages/DownloadStats.js";
import { SolveChallengePage } from "./pages/SolveChallengePage.js";

export function Routing(): VNode {
  const history = createHashHistory();
  const backend = useBackendState();
  const settings = useSettingsContext();
  const { config } = useBankCoreApiContext();
  const { i18n } = useTranslationContext();

  if (backend.state.status === "loggedOut") {
    return <BankFrame >
      <Router history={history}>
        <Route
          path="/login"
          component={() => (
            <Fragment>
              <div class="sm:mx-auto sm:w-full sm:max-w-sm">
                <h2 class="text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">{i18n.str`Welcome to ${settings.bankName}!`}</h2>
              </div>

              <LoginForm
                onRegister={() => {
                  route("/register");
                }}
              />
            </Fragment>
          )}
        />
        <Route
          path="/public-accounts"
          component={() => <PublicHistoriesPage />}
        />
        <Route
          path="/operation/:wopid"
          component={({ wopid }: { wopid: string }) => (
            <WithdrawalOperationPage
              operationId={wopid}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onContinue={() => {
                route("/account");
              }}
            />
          )}
        />
        {config.allow_registrations &&
          <Route
            path="/register"
            component={() => (
              <RegistrationPage
                onComplete={() => {
                  route("/account");
                }}
                onCancel={() => {
                  route("/account");
                }}
              />
            )}
          />
        }
        <Route default component={Redirect} to="/login" />
      </Router>
    </BankFrame>
  }
  const { isUserAdministrator, username } = backend.state

  return (
    <BankFrame account={username}>
      <Router history={history}>
        <Route
          path="/operation/:wopid"
          component={({ wopid }: { wopid: string }) => (
            <WithdrawalOperationPage
              operationId={wopid}
              onContinue={() => {
                route("/account");
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
            />
          )}
        />
        <Route
          path="/2fa"
          component={({ }: {}) => (
            <SolveChallengePage
              onContinue={() => {
                route("/account");
              }}
            />
          )}
        />
        <Route
          path="/public-accounts"
          component={() => <PublicHistoriesPage />}
        />
        <Route
          path="/download-stats"
          component={() => <DownloadStats
            onCancel={() => {
              route("/account")
            }}
          />}
        />

        <Route
          path="/new-account"
          component={() => <CreateNewAccount
            onCancel={() => {
              route("/account")
            }}
            onCreateSuccess={() => {
              route("/account")
            }}
          />}
        />

        <Route
          path="/profile/:account/details"
          component={({ account }: { account: string }) => (
            <ShowAccountDetails
              account={account}
              onUpdateSuccess={() => {
                route("/account")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onClear={() => {
                route("/account")
              }}
            />
          )}
        />

        <Route
          path="/profile/:account/change-password"
          component={({ account }: { account: string }) => (
            <UpdateAccountPassword
              focus
              account={account}
              onUpdateSuccess={() => {
                route("/account")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account")
              }}
            />
          )}
        />
        <Route
          path="/profile/:account/delete"
          component={({ account }: { account: string }) => (
            <RemoveAccount
              account={account}
              onUpdateSuccess={() => {
                route("/account")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account")
              }}
            />
          )}
        />

        <Route
          path="/profile/:account/cashouts"
          component={({ account }: { account: string }) => (
            <CashoutListForAccount
              account={account}
              onSelected={(cid) => {
                route(`/cashout/${cid}`)
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onClose={() => {
                route("/account")
              }}
            />
          )}
        />

        <Route
          path="/delete-my-account"
          component={() => (
            <RemoveAccount
              account={username}
              onUpdateSuccess={() => {
                route("/")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account")
              }}
            />
          )}
        />
        <Route
          path="/my-profile"
          component={() => (
            <ShowAccountDetails
              account={username}
              onUpdateSuccess={() => {
                route("/account")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onClear={() => {
                route("/account")
              }}
            />
          )}
        />
        <Route
          path="/my-password"
          component={() => (
            <UpdateAccountPassword
              focus
              account={username}
              onUpdateSuccess={() => {
                route("/account")
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account")
              }}
            />
          )}
        />

        <Route
          path="/my-cashouts"
          component={() => (
            <CashoutListForAccount
              account={username}
              onSelected={(cid) => {
                route(`/cashout/${cid}`)
              }}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onClose={() => {
                route("/account");
              }}
            />
          )}
        />

        <Route
          path="/new-cashout"
          component={() => (
            <CreateCashout
              account={username}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account");
              }}
            />
          )}
        />

        <Route
          path="/cashout/:cid"
          component={({ cid }: { cid: string }) => (
            <ShowCashoutDetails
              id={cid}
              onCancel={() => {
                route("/my-cashouts");
              }}
            />
          )}
        />


        <Route
          path="/wire-transfer/:dest"
          component={({ dest }: { dest: string }) => (
            <WireTransfer
              toAccount={dest}
              onAuthorizationRequired={() => {
                route(`/2fa`)
              }}
              onCancel={() => {
                route("/account")
              }}
              onSuccess={() => {
                route("/account")
              }}
            />
          )}
        />

        <Route
          path="/account"
          component={() => {
            if (isUserAdministrator) {
              return <AdminHome
                onAuthorizationRequired={() => {
                  route(`/2fa`)
                }}
                onCreateAccount={() => {
                  route("/new-account")
                }}
                onShowAccountDetails={(aid) => {
                  route(`/profile/${aid}/details`)
                }}
                onRemoveAccount={(aid) => {
                  route(`/profile/${aid}/delete`)
                }}
                onShowCashoutForAccount={(aid) => {
                  route(`/profile/${aid}/cashouts`)
                }}
                onUpdateAccountPassword={(aid) => {
                  route(`/profile/${aid}/change-password`)

                }}
              />;
            } else {
              return <AccountPage
                account={username}
                onAuthorizationRequired={() => {
                  route(`/2fa`)
                }}
                goToConfirmOperation={(wopid) => {
                  route(`/operation/${wopid}`);
                }}
              />
            }
          }}
        />
        <Route default component={Redirect} to="/account" />
      </Router>
    </BankFrame>
  );
}

function Redirect({ to }: { to: string }): VNode {
  useEffect(() => {
    route(to, true);
  }, []);
  return <div>being redirected to {to}</div>;
}
