import {JSONObject, IFormData, IFile, DF_FULL_DATE} from "@fanam-pkg/core-utils"
import {Fragment} from "react"
import {DropDown, TextArea, TextField, Checkbox, RadioButton} from "../../atoms"
import {TextFieldCalendar, ProfileUpload, MultiSelect} from "../../molecules"
import {GroupAttachment} from "../../organisms"
import {
  GroupFormItemProps,
  GroupFormProps,
  FormValueType,
  FormSectionProps,
  CommonSelectionType,
  SelectedType,
} from "../../props"
import styles from "./styles.module.sass"

export const GroupForm = ({formSections, wrapperClass = ""}: GroupFormProps) => {
  const minDate = new Date()
  const maxDate = new Date()
  maxDate.setFullYear(minDate.getFullYear() + 1)

  const renderChild = (child: GroupFormItemProps, index: number) => {
    const {
      error,
      label = "",
      elementType,
      options,
      name,
      value,
      type = "text",
      dateFormat = DF_FULL_DATE,
      pickerType = "date",
      disabled,
      wrapperClass = "",
      onChangeValue,
      radioGroupName,
      option,
      maxLength,
      childTop,
      childBottom,
      childElement,
      helperText,
      inputRegex,
      isRequired = true,
      startDate = minDate,
      endDate = maxDate,
    } = child

    const inputValue = typeof value !== "boolean" && typeof value !== "object" ? value : ""

    const onChange = (data: FormValueType) => {
      if (onChangeValue) onChangeValue(data as JSONObject)
    }

    const onChooseItems = (items: IFormData[] | Record<string, IFormData[]>) => onChange(items as JSONObject)

    const baseProps = {
      name,
      label,
      error,
      disabled,
      helperText,
      isRequired,
    }

    const inputProps = {
      ...baseProps,
      onChangeData: onChange,
      type,
      value: inputValue,
      wrapperClass,
    }

    const checkboxProps = {
      ...baseProps,
      items: options as IFormData[],
      item: option,
      onSelectItem: onChange,
      onSelectItems: onChooseItems,
      wrapperClass: `${styles.single_element} ${wrapperClass}`,
    }

    return (
      <Fragment key={index}>
        {childElement || (
          <>
            {childTop}
            {elementType === "multi-select" ? (
              <MultiSelect {...baseProps} options={options! as IFormData[]} onChangeData={onChange} />
            ) : elementType === "profile-picker" ? (
              <ProfileUpload
                wrapperClass={`${styles.single_element} ${wrapperClass}`}
                onChangeData={onChange}
                name={name}
                value={value as IFile}
                disabled={disabled}
              />
            ) : elementType === "file-picker" ? (
              <GroupAttachment
                {...child}
                wrapperClass={`${styles.single_element} ${wrapperClass}`}
                onChangeData={onChange}
              />
            ) : elementType === "drop-down" ? (
              <DropDown
                {...inputProps}
                options={options!}
                selected={value as SelectedType<CommonSelectionType>}
                onChangeData={onChange}
              />
            ) : elementType === "input" ? (
              <TextField {...inputProps} maxLength={maxLength} inputRegex={inputRegex} />
            ) : elementType === "date-picker" ? (
              <TextFieldCalendar
                {...inputProps}
                startDate={startDate}
                endDate={endDate}
                pickerType={pickerType}
                dateFormat={dateFormat}
              />
            ) : elementType === "text-area" ? (
              <TextArea
                {...inputProps}
                maxLength={maxLength}
                wrapperClass={`${styles.single_element} ${wrapperClass}`}
              />
            ) : elementType === "checkbox" ? (
              <Checkbox {...checkboxProps} />
            ) : elementType === "radio-button" ? (
              <RadioButton {...checkboxProps} radioGroupName={radioGroupName} />
            ) : null}
            {childBottom}
          </>
        )}
      </Fragment>
    )
  }

  const renderFormSection = (
    {title, description, childElements, children, wrapperClassGrid = "", wrapperClass = ""}: FormSectionProps,
    index: number
  ) => (
    <section className={`${styles.form_section} ${wrapperClass}`} key={index}>
      {title && <h5 className={`semi-bold ${styles.form_title}`}>{title}</h5>}
      {description && <p className={styles.form_description}>{description}</p>}
      {childElements && (
        <ul className={`${styles.form_group_list} ${wrapperClassGrid}`}>{childElements?.map(renderChild)}</ul>
      )}
      {children}
    </section>
  )

  return (
    <section className={wrapperClass}>
      {Array.isArray(formSections) ? formSections.map(renderFormSection) : renderFormSection(formSections, 0)}
    </section>
  )
}
