import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, VNode, h } from "preact";
import { useEffect } from "preact/hooks";
import { UIFormProps } from "../FormProvider.js";
import { noHandlerPropsAndNoContextForField } from "./InputArray.js";
import { LabelWithTooltipMaybeRequired } from "./InputLine.js";

/**
 * Choice of a translated string, with attached description
 * of the choice.
 *
 * The value is usually a string or numeric constant.
 */
export interface ChoiceS<V> {
  label: TranslatedString;
  description?: TranslatedString;
  value: V;
}

export function InputChoiceStacked<Choices>(
  props: {
    choices: ChoiceS<Choices>[];
  } & UIFormProps<Choices>,
): VNode {
  const { choices, name, label, tooltip, help, hidden, required, converter } =
    props;

  const { value, onChange } =
    props.handler ?? noHandlerPropsAndNoContextForField(props.name);

  if (hidden) {
    return <Fragment />;
  }

  useEffect(() => {
    // Reset choice if value is set to a choices that's
    // not available to this input.
    for (const choice of choices) {
      if (choice.value === value) {
        return;
      }
    }
    onChange(undefined);
  }, []);

  return (
    <div class="sm:col-span-6">
      <LabelWithTooltipMaybeRequired
        label={label}
        required={required}
        tooltip={tooltip}
        name={props.name as string}
      />
      <fieldset class="mt-2">
        <div class="space-y-4">
          {choices.map((choice, idx) => {
            let clazz =
              "border relative block cursor-pointer rounded-lg bg-white px-6 py-4 shadow-sm focus:outline-none sm:flex sm:justify-between data-[disabled=true]:cursor-not-allowed data-[disabled=true]:bg-gray-50 data-[disabled=true]:text-gray-500 ";
            if (choice.value === value) {
              clazz +=
                " border-transparent border-indigo-600 ring-2 ring-indigo-600";
            } else {
              clazz += " border-gray-300";
            }

            return (
              <label key={idx} class={clazz} data-disabled={props.disabled}>
                <input
                  type="radio"
                  name="server-size"
                  disabled={props.disabled}
                  value={
                    (!converter
                      ? (choice.value as string)
                      : converter?.toStringUI(choice.value)) ?? ""
                  }
                  onClick={(e) => {
                    onChange(
                      (value === choice.value
                        ? undefined
                        : choice.value) as any,
                    );
                  }}
                  class="sr-only"
                  aria-labelledby="server-size-0-label"
                  aria-describedby="server-size-0-description-0 server-size-0-description-1"
                />
                <span class="flex items-center">
                  <span class="flex flex-col text-sm">
                    <span
                      id="server-size-0-label"
                      class="font-medium text-gray-900"
                    >
                      {choice.label}
                    </span>
                    {choice.description !== undefined && (
                      <span
                        id="server-size-0-description-0"
                        class="text-gray-500"
                      >
                        <span class="block sm:inline">
                          {choice.description}
                        </span>
                      </span>
                    )}
                  </span>
                </span>
              </label>
            );
          })}
        </div>
      </fieldset>
      {help && (
        <p class="mt-2 text-sm text-gray-500" id="email-description">
          {help}
        </p>
      )}
    </div>
  );
}
