import { Field, FormikValues } from 'formik'
import _map from 'lodash/map'
import React, { FC } from 'react'

import { replaceVarInString } from '../../utils'
import {
  CheckboxField,
  CustomField,
  NativeSelectField,
  PhoneNumberField,
} from '../common'
import { DatePickerField } from '../common/DatePickerField'
import { getValidateFunctions } from './utils'
import {ThemeOptions} from "@mui/material";
import {CSSProperties} from "@mui/styles";

const isDocumentDefined = typeof document !== 'undefined'

export interface IFieldsSectionProps {
  formFields?: IFormFieldsSection[];
  values: FormikValues;
  setFieldValue: (
    field: string,
    value: FormikValues,
    shouldValidate?: boolean | undefined
  ) => void;

  countries?: { [key: string]: string | number }[];
  theme?: 'dark' | 'light';
  themeOptions?: ThemeOptions & {
    input?: CSSProperties;
    checkbox?: CSSProperties;
  };
  containerClass?: string;
}

const SectionContainer: FC<{ className: string }> = ({
  children,
  className,
}) => <div className={className}>{children}</div>

const insertHTML = (elementId: string, text = '') => {
  if (isDocumentDefined) {
    const elem = document && document.getElementById(elementId)

    if (!elem?.childNodes.length) {
      elem?.insertAdjacentHTML('afterbegin', text)
    }
  }

  return null
}

const getFieldClassNames = (id: string, existingClassNames: string) => {
  if (isDocumentDefined) {
    const elem = document && document.getElementById(id)

    if ((elem?.parentElement?.clientWidth || 0) < 375) {
      return existingClassNames + ' full-width'
    }
  }

  return existingClassNames
}

export const FieldsSection = ({
  formFields = [],

  countries = [],

  values,
  setFieldValue,
  theme,
  containerClass = '',
  themeOptions,
}: IFieldsSectionProps) => (
  <>
    {_map(formFields, (item, index) => {
      const {
        name,
        groupLabel,
        groupLabelVars = [],
        groupLabelClassName,
        groupClassName = '',
        fields,
      } = item
      return (
        <SectionContainer key={name} className={groupClassName}>
          <span id={`group_label_${index}`} className={groupLabelClassName}>
            {typeof groupLabel === 'string'
              ? insertHTML(
                  `group_label_${index}`,
                  replaceVarInString(groupLabel, groupLabelVars)
                )
              : groupLabel}
          </span>
          <div className={`fields-container ${groupClassName}`}>
            {_map(fields, (fieldData, fieldIndex) => {
              const {
                name,
                label,
                className = 'full-width',
                type,
                component,
                options = [],
              } = fieldData
              const id = `${name}-${fieldIndex}`
              const classNames = `${containerClass}-container__field ${className}`

              return (
                component || (
                  <div
                    key={name}
                    id={id}
                    className={getFieldClassNames(id, classNames)}
                  >
                    <Field
                      name={name}
                      label={label}
                      type={type}
                      validate={getValidateFunctions({
                        element: fieldData,
                        values,
                      })}
                      setFieldValue={setFieldValue}
                      component={
                        type === 'checkbox'
                          ? CheckboxField
                          : type === 'select'
                          ? NativeSelectField
                          : type === 'phone'
                          ? PhoneNumberField
                          : type === 'date'
                          ? DatePickerField
                          : CustomField
                      }
                      selectOptions={name === 'country' ? countries : options}
                      theme={theme}
                      themeOptions={themeOptions}
                    />
                  </div>
                )
              )
            })}
          </div>
        </SectionContainer>
      )
    })}
  </>
)
