import { ErrorType, HttpResponsePaginated, RequestError, notify, notifyError, useTranslationContext } from "@gnu-taler/web-util/browser";
import { VNode, h, Fragment } from "preact";
import { useAccountDetails } from "../../hooks/access.js";
import { useAdminAccountAPI } from "../../hooks/circuit.js";
import { Amounts, HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util";
import { buildRequestErrorMessage, undefinedIfEmpty } from "../../utils.js";
import { useEffect, useRef, useState } from "preact/hooks";
import { ShowInputErrorLabel } from "../../components/ShowInputErrorLabel.js";

export function RemoveAccount({
  account,
  onCancel,
  onUpdateSuccess,
  onLoadNotOk,
  focus,
}: {
  onLoadNotOk: <T>(
    error: HttpResponsePaginated<T, SandboxBackend.SandboxError>,
  ) => VNode;
  focus?: boolean;
  onCancel: () => void;
  onUpdateSuccess: () => void;
  account: string;
}): VNode {
  const { i18n } = useTranslationContext();
  const result = useAccountDetails(account);
  const [accountName, setAccountName] = useState<string | undefined>()
  const { deleteAccount } = useAdminAccountAPI();

  if (!result.ok) {
    if (result.loading || result.type === ErrorType.TIMEOUT) {
      return onLoadNotOk(result);
    }
    if (result.status === HttpStatusCode.NotFound) {
      return <div>account not found</div>;
    }
    return onLoadNotOk(result);
  }
  const ref = useRef<HTMLInputElement>(null);
  useEffect(() => {
    if (focus) ref.current?.focus();
  }, [focus]);

  //FIXME: libeufin does not follow the spec
  const balance = Amounts.parse(result.data.balance);
  // const balance = Amounts.parse(result.data.balance.amount);
  if (!balance) {
    return <div>there was an error reading the balance</div>;
  }
  const isBalanceEmpty = Amounts.isZero(balance);
  if (!isBalanceEmpty) {
    return <div>
      <div class="rounded-md bg-yellow-50 p-4">
        <div class="flex">
          <div class="flex-shrink-0">
            <svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
              <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
            </svg>
          </div>
          <div class="ml-3">
            <h3 class="text-sm font-medium text-yellow-800">
              <i18n.Translate>Can't delete the account</i18n.Translate>
            </h3>
            <div class="mt-2 text-sm text-yellow-700">
              <p>
                <i18n.Translate>The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.</i18n.Translate>
              </p>
            </div>
          </div>

        </div>
      </div>
      <div class="mt-2 flex justify-end">
        <button type="button" class="rounded-md ring-1 ring-gray-400 bg-white px-3 py-2 text-sm font-semibold shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 "
          onClick={() => {
            onCancel()
          }}>
          <i18n.Translate>Go back</i18n.Translate>
        </button>
      </div>
    </div>
  }

  async function doRemove() {
    try {
      const r = await deleteAccount(account);
      onUpdateSuccess();
    } catch (error) {
      if (error instanceof RequestError) {
        notify(
          buildRequestErrorMessage(i18n, error.cause, {
            onClientError: (status) =>
              status === HttpStatusCode.Forbidden
                ? i18n.str`The administrator specified a institutional username`
                : status === HttpStatusCode.NotFound
                  ? i18n.str`The username was not found`
                  : status === HttpStatusCode.PreconditionFailed
                    ? i18n.str`Balance was not zero`
                    : undefined,
          }),
        );
      } else {
        notifyError(i18n.str`Operation failed, please report`,
          (error instanceof Error
            ? error.message
            : JSON.stringify(error)) as TranslatedString);
      }
    }
  }

  const errors = undefinedIfEmpty({
    accountName: !accountName
      ? i18n.str`required`
      : account !== accountName
        ? i18n.str`name doesn't match`
        : undefined,
  });


  return (
    <div>
      <div class="rounded-md bg-yellow-50 p-4">
        <div class="flex">
          <div class="flex-shrink-0">
            <svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
              <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
            </svg>
          </div>
          <div class="ml-3">
            <h3 class="text-sm font-bold text-yellow-800">
              <i18n.Translate>You are going to remove the account</i18n.Translate>
            </h3>
            <div class="mt-2 text-sm text-yellow-700">
              <p>
                <i18n.Translate>This step can't be undone.</i18n.Translate>
              </p>
            </div>
          </div>

        </div>
      </div>

      <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
        <div class="px-4 sm:px-0">
          <h2 class="text-base font-semibold leading-7 text-gray-900">
            <i18n.Translate>Deleting account "{account}"</i18n.Translate>
          </h2>
        </div>
        <form
          class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2"
          autoCapitalize="none"
          autoCorrect="off"
          onSubmit={e => {
            e.preventDefault()
          }}
        >
          <div class="px-4 py-6 sm:p-8">
            <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">

              <div class="sm:col-span-5">
                <label
                  class="block text-sm font-medium leading-6 text-gray-900"
                  for="password"
                >
                  {i18n.str`Verification`}
                </label>
                <div class="mt-2">
                  <input
                    ref={ref}
                    type="text"
                    class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    name="password"
                    id="password"
                    data-error={!!errors?.accountName && accountName !== undefined}
                    value={accountName ?? ""}
                    onChange={(e) => {
                      setAccountName(e.currentTarget.value)
                    }}
                    placeholder={account}
                    autocomplete="off"
                  />
                  <ShowInputErrorLabel
                    message={errors?.accountName}
                    isDirty={accountName !== undefined}
                  />
                </div>
                <p class="mt-2 text-sm text-gray-500" >
                  <i18n.Translate>enter the account name that is going to be deleted</i18n.Translate>
                </p>
              </div>



            </div>
          </div>
          <div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
            {onCancel ?
              <button type="button" class="text-sm font-semibold leading-6 text-gray-900"
                onClick={onCancel}
              >
                <i18n.Translate>Cancel</i18n.Translate>
              </button>
              : <div />
            }
            <button type="submit"
              class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
              disabled={!!errors}
              onClick={(e) => {
                e.preventDefault()
                doRemove()
              }}
            >
              <i18n.Translate>Delete</i18n.Translate>
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
