import { notifyInfo, useLocalNotification, useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
import { useBankCoreApiContext } from "../../context/config.js";
import { useBackendState } from "../../hooks/backend.js";
import { undefinedIfEmpty, withRuntimeErrorHandling } from "../../utils.js";
import { doAutoFocus } from "../PaytoWireTransferForm.js";
import { ProfileNavigation } from "../ProfileNavigation.js";
import { assertUnreachable } from "../WithdrawalOperationPage.js";
import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";

export function UpdateAccountPassword({
  account: accountName,
  onCancel,
  onUpdateSuccess,
  focus,
}: {
  onCancel: () => void;
  focus?: boolean,
  onUpdateSuccess: () => void;
  account: string;
}): VNode {
  const { i18n } = useTranslationContext();
  const { state: credentials } = useBackendState();
  const token = credentials.status !== "loggedIn" ? undefined : credentials.token
  const { api } = useBankCoreApiContext();

  const [current, setCurrent] = useState<string | undefined>();
  const [password, setPassword] = useState<string | undefined>();
  const [repeat, setRepeat] = useState<string | undefined>();

  const accountIsTheCurrentUser = credentials.status === "loggedIn" ?
    credentials.username === accountName : false

  const errors = undefinedIfEmpty({
    current: !accountIsTheCurrentUser ? undefined : !current ? i18n.str`required` : undefined,
    password: !password ? i18n.str`required` : undefined,
    repeat: !repeat
      ? i18n.str`required`
      : password !== repeat
        ? i18n.str`password doesn't match`
        : undefined,
  });
  const [notification, notify, handleError] = useLocalNotification()


  async function doChangePassword() {
    if (!!errors || !password || !token) return;
    await handleError(async () => {
      const resp = await api.updatePassword({ username: accountName, token }, {
        old_password: current,
        new_password: password,
      });
      if (resp.type === "ok") {
        notifyInfo(i18n.str`Password changed`);
        onUpdateSuccess();
      } else {
        switch (resp.case) {
          case "unauthorized": return notify({
            type: "error",
            title: i18n.str`Not authorized to change the password, maybe the session is invalid.`
          })
          case "not-found": return notify({
            type: "error",
            title: i18n.str`Account not found`
          })
          case "user-require-old-password": return notify({
            type: "error",
            title: i18n.str`Old password need to be provided in order to change new one. If you don't have it contact your account administrator.`
          })
          case "wrong-old-password": return notify({
            type: "error",
            title: i18n.str`Your current password doesn't match, can't change to a new password.`
          })
          default: assertUnreachable(resp)
        }
      }
    })
  }

  return (
    <Fragment>
      <LocalNotificationBanner notification={notification} />
      {accountIsTheCurrentUser ?
        <ProfileNavigation current="credentials" noCashout={credentials.status === "loggedIn" ? credentials.isUserAdministrator : undefined} /> :
        <h1 class="text-base font-semibold leading-6 text-gray-900">
          <i18n.Translate>Account "{accountName}"</i18n.Translate>
        </h1>

      }

      <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>Update password</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`New password`}
                </label>
                <div class="mt-2">
                  <input
                    ref={focus ? doAutoFocus : undefined}
                    type="password"
                    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?.password && password !== undefined}
                    value={password ?? ""}
                    onChange={(e) => {
                      setPassword(e.currentTarget.value)
                    }}
                    autocomplete="off"
                  />
                  <ShowInputErrorLabel
                    message={errors?.password}
                    isDirty={password !== undefined}
                  />
                </div>
              </div>

              <div class="sm:col-span-5">
                <label
                  class="block text-sm font-medium leading-6 text-gray-900"
                  for="repeat"
                >
                  {i18n.str`Type it again`}
                </label>
                <div class="mt-2">
                  <input
                    type="password"
                    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="repeat"
                    id="repeat"
                    data-error={!!errors?.repeat && repeat !== undefined}
                    value={repeat ?? ""}
                    onChange={(e) => {
                      setRepeat(e.currentTarget.value)
                    }}
                    // placeholder=""
                    autocomplete="off"
                  />
                  <ShowInputErrorLabel
                    message={errors?.repeat}
                    isDirty={repeat !== undefined}
                  />
                </div>
                <p class="mt-2 text-sm text-gray-500" >
                  <i18n.Translate>repeat the same password</i18n.Translate>
                </p>
              </div>

              {accountIsTheCurrentUser ?
                <div class="sm:col-span-5">
                  <label
                    class="block text-sm font-medium leading-6 text-gray-900"
                    for="password"
                  >
                    {i18n.str`Current password`}
                  </label>
                  <div class="mt-2">
                    <input
                      type="password"
                      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="current"
                      id="current-password"
                      data-error={!!errors?.current && current !== undefined}
                      value={current ?? ""}
                      onChange={(e) => {
                        setCurrent(e.currentTarget.value)
                      }}
                      autocomplete="off"
                    />
                    <ShowInputErrorLabel
                      message={errors?.current}
                      isDirty={current !== undefined}
                    />
                  </div>
                  <p class="mt-2 text-sm text-gray-500" >
                    <i18n.Translate>your current password, for security</i18n.Translate>
                  </p>
                </div>
                : undefined}

            </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-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"
              disabled={!!errors}
              onClick={(e) => {
                e.preventDefault()
                doChangePassword()
              }}
            >
              <i18n.Translate>Change</i18n.Translate>
            </button>
          </div>
        </form>
      </div>
    </Fragment>

  );
}