/*
 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 {
  Amounts,
  HttpStatusCode,
  TalerError,
  assertUnreachable,
} from "@gnu-taler/taler-util";
import {
  ErrorLoading,
  Loading,
  RouteDefinition,
  useBankCoreApiContext,
  useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";

import { useBusinessAccounts } from "../../hooks/regional.js";
import { RenderAmount } from "../PaytoWireTransferForm.js";

const TALER_SCREEN_ID = 121;

interface Props {
  routeCreate: RouteDefinition;

  routeShowAccount: RouteDefinition<{ account: string }>;
  routeRemoveAccount: RouteDefinition<{ account: string }>;
  routeUpdatePasswordAccount: RouteDefinition<{ account: string }>;
}

export function AccountList({
  routeCreate,
  routeRemoveAccount,
  routeShowAccount,
  routeUpdatePasswordAccount,
}: Props): VNode {
  const result = useBusinessAccounts();
  const { i18n } = useTranslationContext();
  const { config } = useBankCoreApiContext();

  if (!result) {
    return <Loading />;
  }
  if (result instanceof TalerError) {
    return <ErrorLoading error={result} />;
  }
  switch (result.case) {
    case "ok":
      break;
    case HttpStatusCode.Unauthorized:
      return <Fragment />;
    default:
      assertUnreachable(result);
  }

  const accounts = result.body;
  return (
    <Fragment>
      <div class="px-4 sm:px-6 lg:px-8 mt-8">
        <div class="sm:flex sm:items-center">
          <div class="sm:flex-auto">
            <h1 class="text-base font-semibold leading-6 text-gray-900">
              <i18n.Translate>Accounts</i18n.Translate>
            </h1>
          </div>
          <div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
            <a
              href={routeCreate.url({})}
              name="create account"
              type="button"
              class="block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
            >
              <i18n.Translate>Create account</i18n.Translate>
            </a>
          </div>
        </div>
        <div class="mt-4 flow-root">
          <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
            <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
              {!accounts.length ? (
                <div>{/* FIXME: ADD empty list */}</div>
              ) : (
                <table class="min-w-full divide-y divide-gray-300">
                  <thead>
                    <tr>
                      <th
                        scope="col"
                        class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0"
                      >{i18n.str`Username`}</th>
                      <th
                        scope="col"
                        class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
                      >{i18n.str`Name`}</th>
                      <th
                        scope="col"
                        class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
                      >{i18n.str`Balance`}</th>
                      <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-0">
                        <span class="sr-only">{i18n.str`Actions`}</span>
                      </th>
                    </tr>
                  </thead>
                  <tbody class="divide-y divide-gray-200">
                    {accounts.map((item, idx) => {
                      const balance = !item.balance
                        ? undefined
                        : Amounts.parse(item.balance.amount);
                      const noBalance = Amounts.isZero(item.balance.amount);
                      const balanceIsDebit =
                        item.balance &&
                        item.balance.credit_debit_indicator == "debit";

                      return (
                        <tr
                          key={idx}
                          class="data-[status=deleted]:bg-gray-100"
                          data-status={item.status}
                        >
                          <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">
                            <a
                              name={`show account ${item.username}`}
                              href={routeShowAccount.url({
                                account: item.username,
                              })}
                              class="text-indigo-600 hover:text-indigo-900"
                            >
                              {item.username}
                            </a>
                          </td>
                          <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
                            {item.name}
                          </td>
                          <td
                            data-negative={
                              noBalance
                                ? undefined
                                : balanceIsDebit
                                  ? "true"
                                  : "false"
                            }
                            class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 data-[negative=false]:text-green-600 data-[negative=true]:text-red-600 "
                          >
                            {!balance ? (
                              i18n.str`Unknown`
                            ) : (
                              <span class="amount">
                                <RenderAmount
                                  value={balance}
                                  negative={balanceIsDebit}
                                  withSign
                                  spec={config.currency_specification}
                                />
                              </span>
                            )}
                          </td>
                          <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
                            {item.status === "deleted" ? (
                              <p class="text-gray-600">removed</p>
                            ) : (
                              <Fragment>
                                <a
                                  name={`update password ${item.username}`}
                                  href={routeUpdatePasswordAccount.url({
                                    account: item.username,
                                  })}
                                  class="text-indigo-600 hover:text-indigo-900"
                                >
                                  <i18n.Translate>
                                    Change password
                                  </i18n.Translate>
                                </a>
                                <br />

                                {noBalance ? (
                                  <a
                                    name={`remove account ${item.username}`}
                                    href={routeRemoveAccount.url({
                                      account: item.username,
                                    })}
                                    class="text-indigo-600 hover:text-indigo-900"
                                  >
                                    <i18n.Translate>Remove</i18n.Translate>
                                  </a>
                                ) : undefined}
                              </Fragment>
                            )}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              )}
            </div>
            <nav
              class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6 rounded-lg"
              aria-label="Pagination"
            >
              <div class="flex flex-1 justify-between sm:justify-end">
                <button
                  name="first page"
                  class="relative disabled:bg-gray-100 disabled:text-gray-500 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0"
                  disabled={!result.loadFirst}
                  onClick={result.loadFirst}
                >
                  <i18n.Translate>First page</i18n.Translate>
                </button>
                <button
                  name="next page"
                  class="relative disabled:bg-gray-100 disabled:text-gray-500 ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0"
                  disabled={!result.loadNext}
                  onClick={result.loadNext}
                >
                  <i18n.Translate>Next</i18n.Translate>
                </button>
              </div>
            </nav>
          </div>
        </div>
      </div>
    </Fragment>
  );
}
