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

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

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

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: undefined,
    name: undefined,
    description: undefined,
    description_i18n: {},
    kind: TalerMerchantApi.TokenFamilyKind.Discount,
    duration: Duration.toTalerProtocolDuration(Duration.getForever()),
    valid_after: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.never()),
    valid_before: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.never()),
    validity_granularity: Duration.toTalerProtocolDuration(Duration.getForever()),
  });

  const { i18n } = useTranslationContext();

  const errors: FormErrors<Entity> = {
    slug: !value.slug ? i18n.str`Required` : undefined,
    name: !value.name ? i18n.str`Required` : undefined,
    description: !value.description ? i18n.str`Required` : undefined,
    valid_after: !value.valid_after ? undefined : undefined,
    valid_before: !value.valid_before ? i18n.str`Required` : undefined,
    validity_granularity: !value.validity_granularity ? i18n.str`Required` : undefined,
    duration: !value.duration ? i18n.str`Required` : undefined,
    kind: !value.kind ? i18n.str`Required` : undefined,
  };

  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();

  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="validity_granularity"
          label={i18n.str`Validity Granularity`}
          tooltip={i18n.str`Rounding granularity for the start validity of keys, must be 1 minute, 1 hour, 1 day, 1 week, 30 days or 90 days`}
          useProtocolDuration
        />
        <InputDuration<Entity>
          name="duration"
          label={i18n.str`Duration`}
          tooltip={i18n.str`Validity duration of a issued token`}
          withForever
          useProtocolDuration
        />
      </FormProvider>
    </div>
  );
}
