import {
  h, Component, useProp, useRef, useEvent,
} from "atomico";
import { Maybe } from "purify-ts/es/Maybe";
import { Option } from "funfix";
import style from "./kun-form.scss";
import { getComponentOrDefine } from "../../hooks/aync-hook/redirect";

export interface OptionItem {
  label: string;
  value: string;
}

export interface FormPropTypes<T> {
    name: string;
    formType: "select"|"input"|"textarea" |"checkbox" | "hidden";
    defaultValue?: T;
    placeholder?: string;
    label: string;
    value?: T;
    options?: OptionItem[];
}

const KunForm = () => {
  const formRef = useRef<HTMLFormElement>();
  const [parseForm] = useProp<boolean>("parseForm");
  const defaultFields: FormPropTypes<string>[] = [{
    name: "abc",
    label: "标题",
    formType: "input",
  }];

  const submitEvent = useEvent("MySubmit", {
    composed: true,
    bubbles: true,
  });

  const onSubmitForm = (event: MouseEvent): void => {
    const formData = new FormData(formRef.current);

    let retResult: FormData|string = formData;
    if (parseForm) {
      retResult = JSON.parse(JSON.stringify(Array.from(formData.entries()).reduce((memo, pair) => ({
        ...memo,
        [pair[0]]: pair[1],
      }), {})));
    }
    submitEvent({
      form: retResult,
    });

    event.preventDefault();
    event.stopPropagation();
  };

  const [fields] = useProp<FormPropTypes<string>[]>("fields");
  const checkedFields = Maybe.fromPredicate(
    (r: FormPropTypes<string>[]) => r.length > 0,
  )(fields).orDefault(defaultFields);
  const [submitText] = useProp<string>("submitText");
  const checkedSubmitText = Option.of(submitText).getOrElse("提交");

  return (
    <host>
      <style>{style}</style>
      <form className="pt-6" onsubmit={onSubmitForm} ref={formRef}>
        {
          checkedFields.map((item) => (
            <div className="mb-4">
              { item.formType !== "hidden" && (
              <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor={item.name}>
                {item.label}
              </label>
              )}
              {
                item.formType === "textarea" && (
                <textarea
                  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                  name={item.name}
                  id={item.name}
                  value={item.value}
                  placeholder={item.placeholder}
                />
                )
              }
              {
                item.formType === "hidden" && (
                <input
                  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                  name={item.name}
                  id={item.name}
                  value={item.value}
                  type="hidden"
                  placeholder={item.placeholder}
                />
                )
              }
              {
                item.formType === "input" && (
                <input
                  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                  name={item.name}
                  id={item.name}
                  value={item.value}
                  type="text"
                  placeholder={item.placeholder}
                />
                )
              }
              {
                item.formType === "select" && (
                <select
                  name={item.name}
                  id={item.name}
                  className="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
                >
                  {
                    (item.options ?? []).map((itm: OptionItem) => (<option value={itm.value}>{itm.label}</option>))
                  }
                </select>
                )
              }
            </div>
          ))
        }
        <div className="flex items-center justify-between">
          <button
            onclick={onSubmitForm}
            className="bg-orange-400 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
            type="submit"
          >
            {checkedSubmitText}
          </button>
        </div>
      </form>
    </host>
  );
};

KunForm.props = {
  fields: {
    type: Array,
    value: [],
    reflect: true,
  },
  parseForm: {
    type: Boolean,
    value: true,
    reflect: true,
  },

  submitText: {
    type: String,
    value: "提交",
    reflect: true,
    event: {
      type: "changeMessage",
    },
  },
};

export default getComponentOrDefine("kun-form", KunForm);
