import React, { ChangeEvent, ReactElement, useState } from 'react'
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
import Input, { InputProps } from '@shared/FormInput'
import FormActions from './FormActions'
import styles from './FormEdit.module.css'
import { FormPublishData } from '../../Publish/_types'
import { useAsset } from '@context/Asset'
import { MetadataEditForm } from './_types'

export function checkIfTimeoutInPredefinedValues(
  timeout: string,
  timeoutOptions: string[]
): boolean {
  if (timeoutOptions.indexOf(timeout) > -1) {
    return true
  }
  return false
}

function handleTimeoutCustomOption(
  data: FormFieldContent[],
  values: Partial<FormPublishData>
) {
  const timeoutFieldContent = data.filter(
    (field) => field.name === 'timeout'
  )[0]
  const timeoutInputIndex = data.findIndex(
    (element) => element.name === 'timeout'
  )
  if (
    data[timeoutInputIndex].options.length < 6 &&
    !checkIfTimeoutInPredefinedValues(
      values?.services[0]?.timeout,
      timeoutFieldContent.options
    )
  ) {
    data[timeoutInputIndex].options.push(values?.services[0]?.timeout)
  } else if (
    data[timeoutInputIndex].options.length === 6 &&
    checkIfTimeoutInPredefinedValues(
      values?.services[0]?.timeout,
      timeoutFieldContent.options
    )
  ) {
    data[timeoutInputIndex].options.pop()
  } else if (
    data[timeoutInputIndex].options.length === 6 &&
    data[timeoutInputIndex].options[5] !== values?.services[0]?.timeout
  ) {
    data[timeoutInputIndex].options[5] = values?.services[0]?.timeout
  }
}

export default function FormEditMetadata({
  data,
  setTimeoutStringValue,
  values,
  showPrice,
  isComputeDataset
}: {
  data: InputProps[]
  setTimeoutStringValue: (value: string) => void
  values: Partial<MetadataEditForm>
  showPrice: boolean
  isComputeDataset: boolean
}): ReactElement {
  const { oceanConfig } = useAsset()
  const [showEdit, setShowEdit] = useState<boolean>()
  const {
    validateField,
    setFieldValue
  }: FormikContextType<Partial<MetadataEditForm>> = useFormikContext()

  // Manually handle change events instead of using `handleChange` from Formik.
  // Workaround for default `validateOnChange` not kicking in
  function handleFieldChange(
    e: ChangeEvent<HTMLInputElement>,
    field: InputProps
  ) {
    validateField(field.name)
    setFieldValue(field.name, e.target.value)
  }
  // This component is handled by Formik so it's not rendered like a "normal" react component,
  // so handleTimeoutCustomOption is called only once.
  // https://github.com/oceanprotocol/market/pull/324#discussion_r561132310
  // if (data && values) handleTimeoutCustomOption(data, values)

  const timeoutOptionsArray = data.filter(
    (field) => field.name === 'timeout'
  )[0].options

  if (isComputeDataset && timeoutOptionsArray.includes('Forever')) {
    const foreverOptionIndex = timeoutOptionsArray.indexOf('Forever')
    timeoutOptionsArray.splice(foreverOptionIndex, 1)
  } else if (!isComputeDataset && !timeoutOptionsArray.includes('Forever')) {
    timeoutOptionsArray.push('Forever')
  }

  return (
    <Form className={styles.form}>
      {data.map(
        (field: InputProps) =>
          (!showPrice && field.name === 'price') || (
            <Field
              key={field.name}
              options={
                field.name === 'timeout' && isComputeDataset === true
                  ? timeoutOptionsArray
                  : field.options
              }
              {...field}
              component={Input}
              prefix={field.name === 'price' && oceanConfig.oceanTokenSymbol}
              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                handleFieldChange(e, field)
              }
            />
          )
      )}

      <FormActions
        setShowEdit={setShowEdit}
        // handleClick={() => setTimeoutStringValue(values?.services[0]?.timeout)}
      />
    </Form>
  )
}
