/*
 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 {
  DecimalNumber,
  RoundingMode,
  TalerCorebankApi
} from "@gnu-taler/taler-util";
import {
  ShowInputErrorLabel,
  useTranslationContext
} from "@gnu-taler/web-util/browser";
import { ComponentChildren, VNode, h } from "preact";
import { useState } from "preact/hooks";
import { useSessionState } from "../../hooks/session.js";
import { ErrorMessageMappingFor, undefinedIfEmpty } from "../../utils.js";
import { doAutoFocus } from "../PaytoWireTransferForm.js";

const TALER_SCREEN_ID = 129;

export type ConversionRateClassFormData = {
  name?: string;
  description?: string;

  cashin_enabled?: boolean;
  cashin_min_amount?: string;
  cashin_ratio?: string;
  cashin_fee?: string;
  cashin_rounding_mode?: RoundingMode;

  cashout_enabled?: boolean;
  cashout_min_amount?: string;
  cashout_ratio?: DecimalNumber;
  cashout_fee?: string;
  cashout_rounding_mode?: RoundingMode;
};

// type ChangeByPurposeType = {
//   create: (a: TalerCorebankApi.ConversionRateClassInput | undefined) => void;
//   update: (a: TalerCorebankApi.ConversionRateClassInput | undefined) => void;
//   show: undefined;
// };
/**
 *
 * @param param0
 * @returns
 */
export function ConversionRateClassForm(
  // <
  //   PurposeType extends keyof ChangeByPurposeType,
  // >
  {
    onChange,
    focus,
    children,
  }: {
    focus?: boolean;
    children: ComponentChildren;
    // onChange: ChangeByPurposeType[PurposeType];
    onChange: (
      a: TalerCorebankApi.ConversionRateClassInput | undefined,
    ) => void;
  },
): VNode {
  // const { config, url } = useBankCoreApiContext();
  const { i18n } = useTranslationContext();
  const { state: credentials } = useSessionState();
  const [form, setForm] = useState<ConversionRateClassFormData>({});

  const [errors, setErrors] = useState<
    ErrorMessageMappingFor<ConversionRateClassFormData> | undefined
  >(undefined);

  // const defaultValue: ConversionRateClassFormData = {
  //   // cashin_fee: Amounts.stringifyValue(
  //   //   template?.cashin_fee ?? `${config.currency}:0`,
  //   // ),
  //   // cashin_min_amount: Amounts.stringifyValue(
  //   //   template?.cashin_min_amount ?? `${config.currency}:0`,
  //   // ),
  //   // cashout_fee: Amounts.stringifyValue(
  //   //   template?.cashout_fee ?? `${config.currency}:0`,
  //   // ),
  //   // cashin_ratio: template?.cashin_ratio ?? "0",
  //   // cashin_rounding_mode: template?.cashin_rounding_mode,

  //   // cashout_min_amount: Amounts.stringifyValue(
  //   //   template?.cashout_min_amount ?? `${config.currency}:0`,
  //   // ),
  //   // cashout_ratio: template?.cashout_ratio ?? "0",
  //   // cashout_rounding_mode: template?.cashout_rounding_mode,

  //   // cashin_enabled:
  //   //   template?.cashin_ratio !== undefined &&
  //   //   Number.parseInt(template.cashin_ratio, 10) > 0,

  //   // cashout_enabled:
  //   //   template?.cashout_ratio !== undefined &&
  //   //   Number.parseInt(template.cashout_ratio, 10) > 0,

  //   name: template?.name,
  //   description: template?.description,
  // };

  const userIsAdmin =
    credentials.status !== "loggedIn" ? false : credentials.isUserAdministrator;

  const editableForm = userIsAdmin;

  function updateForm(newForm: ConversionRateClassFormData): void {
    const errors = undefinedIfEmpty<
      ErrorMessageMappingFor<ConversionRateClassFormData>
    >({
      name: !editableForm
        ? undefined // disabled
        : !newForm.name
          ? i18n.str`Required`
          : undefined,
      // cashin_fee:
      //   !editableForm || !newForm.cashin_enabled
      //     ? undefined
      //     : !newForm.cashin_fee
      //       ? i18n.str`Required`
      //         : undefined,
      // cashout_fee:
      //   !editableForm || !newForm.cashout_fee
      //     ? undefined
      //     : !newForm.cashout_fee
      //       ? i18n.str`Required`
      //         : undefined,
      // cashin_min_amount:
      //   !editableForm || !newForm.cashin_min_amount
      //     ? undefined
      //     : !newForm.cashin_min_amount
      //       ? i18n.str`Required`
      //         : undefined,
      // cashout_min_amount:
      //   !editableForm || !newForm.cashout_min_amount
      //     ? undefined
      //     : !newForm.cashout_min_amount
      //       ? i18n.str`Required`
      //         : undefined,
    });
    setErrors(errors);

    setForm(newForm);
    if (!onChange) return;

    if (errors) {
      onChange(undefined);
    } else {
      const result: TalerCorebankApi.ConversionRateClassInput = {
        name: newForm.name!,
        description: newForm.description,
      };
      onChange(result);
      // switch (purpose) {
      //   case "create": {
      //     // typescript doesn't correctly narrow a generic type
      //     const callback = onChange as ChangeByPurposeType["create"];
      //     const result: TalerCorebankApi.ConversionRateClassInput = {
      //       name: newForm.name!,
      //       description: newForm.description,
      //     };
      //     callback(result);
      //     return;
      //   }
      //   case "update": {
      //     // typescript doesn't correctly narrow a generic type
      //     const callback = onChange as ChangeByPurposeType["update"];

      //     const result: TalerCorebankApi.ConversionRateClassInput = {
      //       name: newForm.name!,
      //     };
      //     callback(result);
      //     return;
      //   }
      //   case "show": {
      //     return;
      //   }
      //   default: {
      //     assertUnreachable(purpose);
      //   }
      // }
    }
  }
  return (
    <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="username"
            >
              {i18n.str`Name`}
              {editableForm && <b class="text-[red]"> *</b>}
            </label>
            <div class="mt-2">
              <input
                ref={focus ? doAutoFocus : undefined}
                type="text"
                class="block w-full disabled:bg-gray-100 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="username"
                id="username"
                data-error={!!errors?.name && form.name !== undefined}
                disabled={!editableForm}
                value={form.name ?? ""}
                onChange={(e) => {
                  form.name = e.currentTarget.value;
                  updateForm(structuredClone(form));
                }}
                // placeholder=""
                autocomplete="off"
              />
              <ShowInputErrorLabel
                message={errors?.name}
                isDirty={form.name !== undefined}
              />
            </div>
            <p class="mt-2 text-sm text-gray-500">
              <i18n.Translate>Conversion rate name</i18n.Translate>
            </p>
          </div>

          <div class="sm:col-span-5">
            <label
              class="block text-sm font-medium leading-6 text-gray-900"
              for="username"
            >
              {i18n.str`Description`}
            </label>
            <div class="mt-2">
              <input
                ref={focus ? doAutoFocus : undefined}
                type="text"
                class="block w-full disabled:bg-gray-100 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="username"
                id="username"
                data-error={
                  !!errors?.description && form.description !== undefined
                }
                disabled={!editableForm}
                value={form.description ?? ""}
                onChange={(e) => {
                  form.description = e.currentTarget.value;
                  updateForm(structuredClone(form));
                }}
                // placeholder=""
                autocomplete="off"
              />
              <ShowInputErrorLabel
                message={errors?.description}
                isDirty={form.description !== undefined}
              />
            </div>
            <p class="mt-2 text-sm text-gray-500">
              <i18n.Translate>Short description of the class</i18n.Translate>
            </p>
          </div>

          {/* <InputToggle
            label={i18n.str`Enable cashin`}
            name="cashin"
            threeState={false}
            disabled={!editableForm}
            handler={{
              value: form.cashin_enabled ?? defaultValue.cashin_enabled,
              onChange(v) {
                form.cashin_enabled = v;
                updateForm(structuredClone(form));
              },
              name: "cashin",
            }}
          />
          <InputToggle
            label={i18n.str`Enable cashout`}
            name="cashout"
            threeState={false}
            disabled={!editableForm}
            handler={{
              value: form.cashout_enabled ?? defaultValue.cashout_enabled,
              onChange(v) {
                form.cashout_enabled = v;
                updateForm(structuredClone(form));
              },
              name: "cashout",
            }}
          /> */}

          {/* {!form.cashin_enabled ? undefined : (
            <Fragment>
              <div class="sm:col-span-5">
                <label
                  class="block text-sm font-medium leading-6 text-gray-900"
                  for="channel"
                >
                  {i18n.str`Cashin rounding mode`}
                </label>
                <div class="mt-2 max-w-xl text-sm text-gray-500">
                  <div class="px-4 mt-4 grid grid-cols-1 gap-y-6">
                    {(["nearest", "zero", "up"] as Array<RoundingMode>).map(
                      (ROUNDING_MODE) => {
                        let LABEL: TranslatedString;
                        switch (ROUNDING_MODE) {
                          case "zero": {
                            LABEL = i18n.str`To zero`;
                            break;
                          }
                          case "up": {
                            LABEL = i18n.str`Round up`;
                            break;
                          }
                          case "nearest": {
                            LABEL = i18n.str`To nearest int`;
                            break;
                          }
                          default: {
                            assertUnreachable(ROUNDING_MODE);
                          }
                        }
                        return (
                          <label
                            onClick={(e) => {
                              form.cashin_rounding_mode = ROUNDING_MODE;
                              updateForm(structuredClone(form));
                              e.preventDefault();
                            }}
                            data-disabled={purpose === "show"}
                            data-selected={
                              (form.cashin_rounding_mode ??
                                defaultValue.cashin_rounding_mode) ===
                              ROUNDING_MODE
                            }
                            class="relative flex data-[disabled=false]:cursor-pointer rounded-lg border bg-white data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none border-gray-300 data-[selected=true]:ring-2 data-[selected=true]:ring-indigo-600"
                          >
                            <input
                              type="radio"
                              name="channel"
                              value="Newsletter"
                              class="sr-only"
                            />
                            <span class="flex flex-1">
                              <span class="flex flex-col">
                                <span
                                  id="project-type-0-label"
                                  class="block text-sm font-medium text-gray-900 "
                                >
                                  {LABEL}
                                </span>
                              </span>
                            </span>
                            <svg
                              data-selected={
                                (form.cashin_rounding_mode ??
                                  defaultValue.cashin_rounding_mode) ===
                                ROUNDING_MODE
                              }
                              class="h-5 w-5 text-indigo-600 data-[selected=false]:hidden"
                              viewBox="0 0 20 20"
                              fill="currentColor"
                              aria-hidden="true"
                            >
                              <path
                                fill-rule="evenodd"
                                d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
                                clip-rule="evenodd"
                              />
                            </svg>
                          </label>
                        );
                      },
                    )}
                  </div>
                </div>
              </div>

              <div class="sm:col-span-5">
                <label
                  for="cashin_fee"
                  class="block text-sm font-medium leading-6 text-gray-900"
                >{i18n.str`Cashin fee`}</label>
                <InputAmount
                  name="cashin_fee"
                  left
                  currency={config.currency}
                  value={form.cashin_fee ?? defaultValue.cashin_fee}
                  onChange={
                    !editableForm
                      ? undefined
                      : (e) => {
                          form.cashin_fee = e as AmountString;
                          updateForm(structuredClone(form));
                        }
                  }
                />
                <ShowInputErrorLabel
                  message={
                    errors?.cashin_fee ? String(errors?.cashin_fee) : undefined
                  }
                  isDirty={form.cashin_fee !== undefined}
                />
                <p class="mt-2 text-sm text-gray-500">
                  <i18n.Translate>FIXME.</i18n.Translate>
                </p>
              </div>

              <div class="sm:col-span-5">
                <label
                  for="debit"
                  class="block text-sm font-medium leading-6 text-gray-900"
                >{i18n.str`Cashin min amount`}</label>
                <InputAmount
                  name="debit"
                  left
                  currency={config.currency}
                  value={
                    form.cashin_min_amount ?? defaultValue.cashin_min_amount
                  }
                  onChange={
                    !editableForm
                      ? undefined
                      : (e) => {
                          form.cashin_min_amount = e as AmountString;
                          updateForm(structuredClone(form));
                        }
                  }
                />
                <ShowInputErrorLabel
                  message={
                    errors?.cashin_min_amount
                      ? String(errors?.cashin_min_amount)
                      : undefined
                  }
                  isDirty={form.cashin_min_amount !== undefined}
                />
                <p class="mt-2 text-sm text-gray-500">
                  <i18n.Translate>FIXME.</i18n.Translate>
                </p>
              </div>
            </Fragment>
          )}

          {!form.cashout_enabled ? undefined : (
            <Fragment>
              <div class="sm:col-span-5">
                <label
                  class="block text-sm font-medium leading-6 text-gray-900"
                  for="channel"
                >
                  {i18n.str`Cashout rounding mode`}
                </label>
                <div class="mt-2 max-w-xl text-sm text-gray-500">
                  <div class="px-4 mt-4 grid grid-cols-1 gap-y-6">
                    {(["nearest", "zero", "up"] as Array<RoundingMode>).map(
                      (ROUNDING_MODE) => {
                        let LABEL: TranslatedString;
                        switch (ROUNDING_MODE) {
                          case "zero": {
                            LABEL = i18n.str`To zero`;
                            break;
                          }
                          case "up": {
                            LABEL = i18n.str`Round up`;
                            break;
                          }
                          case "nearest": {
                            LABEL = i18n.str`To nearest int`;
                            break;
                          }
                          default: {
                            assertUnreachable(ROUNDING_MODE);
                          }
                        }
                        return (
                          <label
                            onClick={(e) => {
                              form.cashout_rounding_mode = ROUNDING_MODE;
                              updateForm(structuredClone(form));
                              e.preventDefault();
                            }}
                            data-disabled={purpose === "show"}
                            data-selected={
                              (form.cashout_rounding_mode ??
                                defaultValue.cashout_rounding_mode) ===
                              ROUNDING_MODE
                            }
                            class="relative flex data-[disabled=false]:cursor-pointer rounded-lg border bg-white data-[disabled=true]:bg-gray-200 p-4 shadow-sm focus:outline-none border-gray-300 data-[selected=true]:ring-2 data-[selected=true]:ring-indigo-600"
                          >
                            <input
                              type="radio"
                              name="channel"
                              value="Newsletter"
                              class="sr-only"
                            />
                            <span class="flex flex-1">
                              <span class="flex flex-col">
                                <span
                                  id="project-type-0-label"
                                  class="block text-sm font-medium text-gray-900 "
                                >
                                  {LABEL}
                                </span>
                              </span>
                            </span>
                            <svg
                              data-selected={
                                (form.cashout_rounding_mode ??
                                  defaultValue.cashout_rounding_mode) ===
                                ROUNDING_MODE
                              }
                              class="h-5 w-5 text-indigo-600 data-[selected=false]:hidden"
                              viewBox="0 0 20 20"
                              fill="currentColor"
                              aria-hidden="true"
                            >
                              <path
                                fill-rule="evenodd"
                                d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
                                clip-rule="evenodd"
                              />
                            </svg>
                          </label>
                        );
                      },
                    )}
                  </div>
                </div>
              </div>

              <div class="sm:col-span-5">
                <label
                  for="cashout_min_amount"
                  class="block text-sm font-medium leading-6 text-gray-900"
                >{i18n.str`Cashout min amount`}</label>
                <InputAmount
                  name="cashout_min_amount"
                  left
                  currency={config.currency}
                  value={
                    form.cashout_min_amount ?? defaultValue.cashout_min_amount
                  }
                  onChange={
                    !editableForm
                      ? undefined
                      : (e) => {
                          form.cashout_min_amount = e as AmountString;
                          updateForm(structuredClone(form));
                        }
                  }
                />
                <ShowInputErrorLabel
                  message={
                    errors?.cashout_min_amount
                      ? String(errors?.cashout_min_amount)
                      : undefined
                  }
                  isDirty={form.cashout_min_amount !== undefined}
                />
                <p class="mt-2 text-sm text-gray-500">
                  <i18n.Translate>FIXME.</i18n.Translate>
                </p>
              </div>
              <div class="sm:col-span-5">
                <label
                  for="debit"
                  class="block text-sm font-medium leading-6 text-gray-900"
                >{i18n.str`Cashout fee`}</label>
                <InputAmount
                  name="debit"
                  left
                  currency={config.currency}
                  value={form.cashout_fee ?? defaultValue.cashout_fee}
                  onChange={
                    !editableForm
                      ? undefined
                      : (e) => {
                          form.cashout_fee = e as AmountString;
                          updateForm(structuredClone(form));
                        }
                  }
                />
                <ShowInputErrorLabel
                  message={
                    errors?.cashout_fee
                      ? String(errors?.cashout_fee)
                      : undefined
                  }
                  isDirty={form.cashout_fee !== undefined}
                />
                <p class="mt-2 text-sm text-gray-500">
                  <i18n.Translate>FIXME.</i18n.Translate>
                </p>
              </div>
            </Fragment>
          )} */}
        </div>
      </div>
      {children}
    </form>
  );
}
