/*
 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:
 */
import {
  AbsoluteTime,
  HttpStatusCode,
  TalerCorebankApi,
  TalerErrorCode,
  TranslatedString,
  assertUnreachable,
} from "@gnu-taler/taler-util";
import {
  Attention,
  ButtonBetter,
  LocalNotificationBanner,
  RouteDefinition,
  notifyInfo,
  useBankCoreApiContext,
  useLocalNotificationBetter,
  useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
import { useSessionState } from "../../hooks/session.js";
import { AccountForm } from "./AccountForm.js";

const TALER_SCREEN_ID = 123;

export function CreateNewAccount({
  routeCancel,
  onCreateSuccess,
}: {
  routeCancel: RouteDefinition;
  onCreateSuccess: () => void;
}): VNode {
  const { i18n } = useTranslationContext();
  const { state: credentials } = useSessionState();
  const token =
    credentials.status !== "loggedIn" ? undefined : credentials.token;
  const {
    lib: { bank: api },
  } = useBankCoreApiContext();

  const [submitAccount, setSubmitAccount] = useState<
    TalerCorebankApi.RegisterAccountRequest | undefined
  >();

  const [notification, safeFunctionHandler] = useLocalNotificationBetter();

  const create = safeFunctionHandler(
    api.createAccount.bind(api),
    !submitAccount || !token ? undefined : [token, submitAccount],
  );
  create.onSuccess = (success, token, account) => {
    notifyInfo(i18n.str`Account created with password "${account.password}".`);
    onCreateSuccess();
  };

  create.onFail = (fail) => {
    switch (fail.case) {
      case HttpStatusCode.BadRequest:
        return i18n.str`Server replied that phone or email is invalid`;
      case HttpStatusCode.Unauthorized:
        return i18n.str`The rights to perform the operation are not sufficient`;
      case TalerErrorCode.BANK_REGISTER_USERNAME_REUSE:
        return i18n.str`Account username is already taken`;
      case TalerErrorCode.BANK_REGISTER_PAYTO_URI_REUSE:
        return i18n.str`Account ID is already taken`;
      case TalerErrorCode.BANK_UNALLOWED_DEBIT:
        return i18n.str`Bank ran out of bonus credit.`;
      case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT:
        return i18n.str`Account username can't be used because is reserved`;
      case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT:
        return i18n.str`Only an administrator is allowed to set the debt limit.`;
      case TalerErrorCode.BANK_MISSING_TAN_INFO:
        return i18n.str`No information for the selected authentication channel.`;
      case TalerErrorCode.BANK_TAN_CHANNEL_NOT_SUPPORTED:
        return i18n.str`Authentication channel is not supported.`;
      case TalerErrorCode.BANK_NON_ADMIN_SET_TAN_CHANNEL:
        return i18n.str`Only admin can create accounts with second factor authentication.`;
      case TalerErrorCode.BANK_NON_ADMIN_SET_CONVERSION_RATE_CLASS:
        return i18n.str`Only the administrator can change the conversion rate.`;
      case TalerErrorCode.BANK_CONVERSION_RATE_CLASS_UNKNOWN:
        return i18n.str`The conversion rate class doesn't exist.`;
      case TalerErrorCode.BANK_PASSWORD_TOO_SHORT:
        return i18n.str`The password is too short. Can't have less than 8 characters.`;
      case TalerErrorCode.BANK_PASSWORD_TOO_LONG:
        return i18n.str`The password is too long. Can't have more than 64 characters.`;
      default:
        assertUnreachable(fail);
    }
  };

  if (!(credentials.status === "loggedIn" && credentials.isUserAdministrator)) {
    return (
      <Fragment>
        <Attention type="warning" title={i18n.str`Can't create accounts`}>
          <i18n.Translate>
            Only system admin can create accounts.
          </i18n.Translate>
        </Attention>
        <div class="mt-5 sm:mt-6">
          <a
            href={routeCancel.url({})}
            name="close"
            class="inline-flex w-full justify-center rounded-md bg-indigo-600 px-3 py-2 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>Close</i18n.Translate>
          </a>
        </div>
      </Fragment>
    );
  }

  return (
    <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-6 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
      <LocalNotificationBanner notification={notification} />

      <div class="px-4 sm:px-0">
        <h2 class="text-base font-semibold leading-7 text-gray-900">
          <i18n.Translate>New bank account</i18n.Translate>
        </h2>
      </div>
      <AccountForm
        template={undefined}
        purpose="create"
        onChange={(a) => {
          setSubmitAccount(a);
        }}
      >
        <div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
          <a
            href={routeCancel.url({})}
            name="cancel"
            class="text-sm font-semibold leading-6 text-gray-900"
          >
            <i18n.Translate>Cancel</i18n.Translate>
          </a>
          <ButtonBetter
            type="submit"
            name="create"
            class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 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"
            onClick={create}
          >
            <i18n.Translate>Create</i18n.Translate>
          </ButtonBetter>
        </div>
      </AccountForm>
    </div>
  );
}
