/*
 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 {
  AccessToken,
  AmountJson,
  Amounts,
  AmountString,
  assertUnreachable,
  createNewWalletKycAccount,
  eddsaGetPublic,
  encodeCrock,
  HttpStatusCode,
  opFixedSuccess,
  opKnownFailure,
  signKycAuth,
  signWalletAccountSetup,
  WalletKycRequest
} from "@gnu-taler/taler-util";
import {
  ButtonBetter,
  FormMetadata,
  FormUI,
  LocalNotificationBanner,
  UIHandlerId,
  useExchangeApiContext,
  useLocalNotificationBetter,
  useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, h, VNode } from "preact";
import { useMemo } from "preact/hooks";
import { useFormMeta } from "../../../web-util/src/hooks/useForm.js";

type FormType = {
  amount: AmountJson;
};

type Props = {
  onKycStarted: (token: AccessToken) => void;
};

export function TriggerKyc({ onKycStarted }: Props): VNode {
  const { i18n } = useTranslationContext();
  const [notification, safeFunctionHandler] = useLocalNotificationBetter();
  const { config, lib } = useExchangeApiContext();

  const theForm: FormMetadata = {
    id: "asd",
    version: 1,
    label: i18n.str`Trigger KYC balance`,
    config: {
      type: "double-column",
      sections: [
        {
          title: i18n.str`Trigger KYC Balance`,
          fields: [
            {
              id: "amount" as UIHandlerId,
              type: "amount",
              currency: config.config.currency,
              label: i18n.str`Amount`,
              required: true,
              converterId: "Taler.Amount",
            },
          ],
        },
      ],
    },
  };

  const {
    model: handler,
    status,
    design,
  } = useFormMeta<FormType>(
    theForm,
    {},
    {
      amount: Amounts.parseOrThrow(`${config.config.currency}:1000000`),
    },
  );

  const accountPromise = useMemo(async () => {
    const resp = await lib.exchange.getSeed();
    const extraEntropy = resp.type === "ok" ? resp.body : new Uint8Array();
    return createNewWalletKycAccount(extraEntropy);
  }, [1]);

  const send = safeFunctionHandler(
    async (balance: AmountString) => {
      const account = await accountPromise;
      const limit: WalletKycRequest = {
        balance,
        reserve_pub: account.id,
        reserve_sig: encodeCrock(
          signWalletAccountSetup(account.signingKey, balance),
        ),
      };
      const resp = await lib.exchange.notifyKycBalanceLimit(limit);
      if (resp.type === "ok") {
        return opKnownFailure(HttpStatusCode.Ok);
      }
      if (resp.case === HttpStatusCode.UnavailableForLegalReasons) {
        const paytoHash = resp.body.h_payto;
        const { signingKey } = await accountPromise;
        const merchantPub = eddsaGetPublic(signingKey);
        const accountOwnerSig = encodeCrock(signKycAuth(signingKey));
        const result = await lib.exchange.checkKycStatus({
          accountPub: encodeCrock(merchantPub),
          accountSig: accountOwnerSig,
          paytoHash,
        });
        if (result.type === "ok") {
          return opKnownFailure(HttpStatusCode.Ok);
        }
        switch(result.case) {
          case HttpStatusCode.Ok:
          case HttpStatusCode.Accepted:
            return opFixedSuccess(result.body)
          case HttpStatusCode.Forbidden:
          case HttpStatusCode.NotFound:
          case HttpStatusCode.Conflict:
            return result;
        }
      }
      return resp;
    },
    theForm === undefined || status.status === "fail"
      ? undefined
      : [Amounts.stringify(status.result.amount)],
  );

  send.onSuccess = (success) => {
    onKycStarted(success.access_token);
  };
  send.onFail = (fail) => {
    switch (fail.case) {
      case HttpStatusCode.Ok:
        return i18n.str`No kyc triggered.`;
      case HttpStatusCode.Forbidden:
        return i18n.str`Forbidden.`;
      case HttpStatusCode.NotFound:
        return i18n.str`Not found.`;
      case HttpStatusCode.Conflict:
        return i18n.str`Conflict.`;
      default:
        assertUnreachable(fail);
    }
  };

  return (
    <div class="rounded-lg bg-white px-5 py-6 shadow m-4">
      <LocalNotificationBanner notification={notification} />
      <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
        <FormUI model={handler} design={design} />
      </div>

      <div class="mt-6 flex items-center justify-end gap-x-6">
        <button
          onClick={() => {}}
          class="text-sm font-semibold leading-6 text-gray-900"
        >
          <i18n.Translate>Cancel</i18n.Translate>
        </button>
        <ButtonBetter
          type="submit"
          onClick={send}
          class="disabled:opacity-50 disabled:cursor-default 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>Submit</i18n.Translate>
        </ButtonBetter>
      </div>

      <div class="grid grid-cols-1 gap-x-8 gap-y-4 ">
        <p>
          <i18n.Translate>
            This actions will trigger wallet balance kyc above 1000000
            threshold, the exchange should be properly configured to trigger the
            desired kyc flow.
          </i18n.Translate>
        </p>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000000`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger TOPS Terms of service</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000010`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger GLS onboarding</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000020`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.1</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000030`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.4</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000040`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.5</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000050`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.9</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000060`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.11</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000070`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.12</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000080`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.13</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000090`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.14</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000100`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.15</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000110`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Challenger test</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000120`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.9 customer</i18n.Translate>
          </ButtonBetter>
        </div>
        <div>
          <ButtonBetter
            type="submit"
            onClick={send.withArgs(`${config.config.currency}:1000130`)}
            // disabled={!submitHandler}
            class="disabled:opacity-50 disabled:cursor-default 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>Trigger VQF 902.9 officer</i18n.Translate>
          </ButtonBetter>
        </div>
      </div>
    </div>
  );
}
