/*

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 { ComponentChildren, Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Paths } from "../../InstanceRoutes.js";
import { Notification } from "../../utils/types.js";
import { NavigationBar } from "./NavigationBar.js";
import { Sidebar } from "./SideBar.js";

function getInstanceTitle(path: string): string {
  switch (path) {
    case Paths.key_figures:
      return "Key figures";
    case Paths.critical_errors:
      return "Critical errors";
    case Paths.operating_status:
      return "Operating status";
    case Paths.detail_view:
      return "Inconsistencies";
    case Paths.amount_arithmethic_inconsistency_list:
      return `Amount arithmetic inconsistencies`;
    case Paths.bad_sig_losses_list:
      return `Bad sig losses`;
    case Paths.balance_list:
      return `Balances`;
    case Paths.closure_lag_list:
      return `Closure Lags`;
    case Paths.coin_inconsistency_list:
      return `Coin inconsistencies`;
    case Paths.denomination_key_validity_withdraw_inconsistency_list:
      return `Denomination key validity withdraw inconsistency`;
    case Paths.denomination_pending_list:
      return `Denominations pending`;
    case Paths.denomination_without_sig_list:
      return `Denominations without sigs`;
    case Paths.deposit_confirmation_list:
      return `Deposit confirmations`;
    case Paths.deposit_confirmation_update:
      return `Update deposit confirmation`;
    case Paths.emergency_list:
      return `Emergencies`;
    case Paths.emergency_by_count_list:
      return `Emergencies by count`;
    case Paths.exchange_signkey_list:
      return `Exchange signkeys`;
    case Paths.fee_time_inconsistency_list:
      return `Fee time inconsistencies`;
    case Paths.historic_denomination_revenue_list:
      return `Historic denomination revenue`;
    case Paths.misattribution_in_inconsistency_list:
      return `Misattribution in inconsistencies`;
    case Paths.progress_list:
      return `Progress`;
    case Paths.purse_not_closed_inconsistency_list:
      return `Purse not closed inconsistencies`;
    case Paths.purse_list:
      return `Purses`;
    case Paths.refresh_hanging_list:
      return `Refreshes hanging`;
    case Paths.reserve_balance_insufficient_inconsistency_list:
      return `Reserve balance insufficient inconsistencies`;
    case Paths.reserve_balance_summary_wrong_inconsistency_list:
      return `Reserve balance summary wrong inconsistencies`;
    case Paths.reserve_in_inconsistency_list:
      return `Reserves in inconsistencies`;
    case Paths.reserve_not_closed_inconsistency_list:
      return `Reserves not closed inconsistencies`;
    case Paths.row_inconsistency_list:
      return `Row inconsistencies`;
    case Paths.row_minor_inconsistency_list:
      return `Row minor inconsistencies`;
    case Paths.wire_format_inconsistency_list:
      return `Wire format inconsistencies`;
    case Paths.wire_out_inconsistency_list:
      return `Wire out inconsistencies`;
    case Paths.settings:
      return `Settings`;
    default:
      return "";
  }
}

interface MenuProps {
  title?: string;
  path: string;
  onShowSettings: () => void;
}

function WithTitle({
  title,
  children,
}: {
  title: string;
  children: ComponentChildren;
}): VNode {
  useEffect(() => {
    document.title = `Taler Backoffice: ${title}`;
  }, [title]);
  return <Fragment>{children}</Fragment>;
}

export function Menu({ onShowSettings, title, path }: MenuProps): VNode {
  const [mobileOpen, setMobileOpen] = useState(false);
  const titleWithSubtitle = getInstanceTitle(path.replace("app/#", ""));
  return (
    <WithTitle title={titleWithSubtitle}>
      <div
        class={mobileOpen ? "has-aside-mobile-expanded" : ""}
        onClick={() => setMobileOpen(false)}
      >
        <NavigationBar
          onMobileMenu={() => setMobileOpen(!mobileOpen)}
          title={titleWithSubtitle}
        />

        <Sidebar onShowSettings={onShowSettings} mobile={mobileOpen} />
      </div>
    </WithTitle>
  );
}

interface NotYetReadyAppMenuProps {
  title: string;
  onShowSettings: () => void;
}

interface NotifProps {
  notification?: Notification;
}

export function NotificationCard({
  notification: n,
}: NotifProps): VNode | null {
  if (!n) return null;
  return (
    <div class="notification">
      <div class="columns is-vcentered">
        <div class="column is-12">
          <article
            class={
              n.type === "ERROR"
                ? "message is-danger"
                : n.type === "WARN"
                  ? "message is-warning"
                  : "message is-info"
            }
          >
            <div class="message-header">
              <p>{n.message}</p>
            </div>
            {n.description && (
              <div class="message-body">
                <div>{n.description}</div>
                {n.details && <pre>{n.details}</pre>}
              </div>
            )}
          </article>
        </div>
      </div>
    </div>
  );
}

interface NotConnectedAppMenuProps {
  title: string;
}

export function NotConnectedAppMenu({
  title,
}: NotConnectedAppMenuProps): VNode {
  const [mobileOpen, setMobileOpen] = useState(false);

  useEffect(() => {
    document.title = `Taler Backoffice: ${title}`;
  }, [title]);

  return (
    <div
      class={mobileOpen ? "has-aside-mobile-expanded" : ""}
      onClick={() => setMobileOpen(false)}
    >
      <NavigationBar
        onMobileMenu={() => setMobileOpen(!mobileOpen)}
        title={title}
      />
    </div>
  );
}

export function NotYetReadyAppMenu({
  onShowSettings,
  title,
}: NotYetReadyAppMenuProps): VNode {
  const [mobileOpen, setMobileOpen] = useState(false);

  useEffect(() => {
    document.title = `Taler Backoffice: ${title}`;
  }, [title]);

  return (
    <div
      class={mobileOpen ? "has-aside-mobile-expanded" : ""}
      onClick={() => setMobileOpen(false)}
    >
      <NavigationBar
        onMobileMenu={() => setMobileOpen(!mobileOpen)}
        title={title}
      />
      (
      <Sidebar
        onShowSettings={onShowSettings}
        instance=""
        mobile={mobileOpen}
      />
      )
    </div>
  );
}
