/*
 This file is part of GNU Taler
 (C) 2021-2023 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/>
 */

/**
 *
 * @author Christian Blättler
 */

import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { h } from "preact";
import { useCallback, useEffect, useState } from "preact/hooks";
import * as yup from "yup";
import { TokenFamilyCreateSchema } from "../../schemas/index.js";
import { FormErrors, FormProvider } from "../form/FormProvider.js";
import { Input } from "../form/Input.js";
import { InputWithAddon } from "../form/InputWithAddon.js";
import { InputDate } from "../form/InputDate.js";
import { InputDuration } from "../form/InputDuration.js";
import { InputSelector } from "../form/InputSelector.js";
import { useSessionContext } from "../../context/session.js";
import { TalerMerchantApi } from "@gnu-taler/taler-util";

type Entity = TalerMerchantApi.TokenFamilyCreateRequest;

interface Props {
  onSubscribe: (c?: () => Entity | undefined) => void;
  initial?: Partial<Entity>;
  alreadyExist?: boolean;
}

export function TokenFamilyForm({ onSubscribe }: Props) {
  const [value, valueHandler] = useState<Partial<Entity>>({
    slug: "",
    name: "",
    description: "",
    description_i18n: {},
    kind: TalerMerchantApi.TokenFamilyKind.Discount,
    duration: { d_us: "forever" },
    valid_after: { t_s: "never" },
    valid_before: { t_s: "never" },
  });
  let errors: FormErrors<Entity> = {};

  try {
    TokenFamilyCreateSchema.validateSync(value, {
      abortEarly: false,
    });
  } catch (err) {
    if (err instanceof yup.ValidationError) {
      const yupErrors = err.inner as yup.ValidationError[];
      errors = yupErrors.reduce(
        (prev, cur) =>
          !cur.path ? prev : { ...prev, [cur.path]: cur.message },
        {},
      );
    }
  }
  const hasErrors = Object.keys(errors).some(
    (k) => (errors as any)[k] !== undefined,
  );

  const submit = useCallback((): Entity | undefined => {
    // HACK: Think about how this can be done better
    return value as Entity;
  }, [value]);

  useEffect(() => {
    onSubscribe(hasErrors ? undefined : submit);
  }, [submit, hasErrors]);

  const { state } = useSessionContext();
  const { i18n } = useTranslationContext();

  return (
    <div>
      <FormProvider<Entity>
        name="token_family"
        errors={errors}
        object={value}
        valueHandler={valueHandler}
      >
        <InputWithAddon<Entity>
          name="slug"
          addonBefore={new URL("tokenfamily/", state.backendUrl.href).href}
          label={i18n.str`Slug`}
          tooltip={i18n.str`token family slug to use in URLs (for internal use only)`}
        />
        <InputSelector<Entity>
          name="kind"
          label={i18n.str`Kind`}
          tooltip={i18n.str`token family kind`}
          values={["discount", "subscription"]}
        />
        <Input<Entity>
          name="name"
          inputType="text"
          label={i18n.str`Name`}
          tooltip={i18n.str`user-readable token family name`}
        />
        <Input<Entity>
          name="description"
          inputType="multiline"
          label={i18n.str`Description`}
          tooltip={i18n.str`token family description for customers`}
        />
        <InputDate<Entity>
          name="valid_after"
          label={i18n.str`Valid After`}
          tooltip={i18n.str`token family can issue tokens after this date`}
          withTimestampSupport
        />
        <InputDate<Entity>
          name="valid_before"
          label={i18n.str`Valid Before`}
          tooltip={i18n.str`token family can issue tokens until this date`}
          withTimestampSupport
        />
        <InputDuration<Entity>
          name="duration"
          label={i18n.str`Duration`}
          tooltip={i18n.str`validity duration of a issued token`}
          withForever
        />
      </FormProvider>
    </div>
  );
}
