import { useState, useEffect, useContext } from 'react'
import { Form, message } from 'antd'
import { ApiServerContext } from '../context/ApiServerContext'
import PropTypes from 'prop-types'

/**
 * NewObjectForm is a reusable form component for creating new objects.
 * It handles form validation, submission, and error handling logic.
 *
 * Props:
 * - type: string (required)
 * - formItems: array (for ObjectInfo/ObjectProperty items)
 * - defaultValues: object (optional) - initial values for the form
 * - children: function({
 *     loading, isSubmitting, handleSubmit, form, formValid, objectData, setObjectData
 *   }) => ReactNode
 */
const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
  const [objectData, setObjectData] = useState(defaultValues)
  const [submitLoading, setSubmitLoading] = useState(false)
  const [formValid, setFormValid] = useState(false)
  const [form] = Form.useForm()
  const formUpdateValues = Form.useWatch([], form)
  const [messageApi, contextHolder] = message.useMessage()
  const { createObject, showError } = useContext(ApiServerContext)

  // Set initial form values when defaultValues change
  useEffect(() => {
    if (Object.keys(defaultValues).length > 0) {
      form.setFieldsValue(defaultValues)
    }
  }, [form, defaultValues])

  // Validate form on change
  useEffect(() => {
    form
      .validateFields({ validateOnly: true })
      .then(() => setFormValid(true))
      .catch(() => setFormValid(false))
  }, [form, formUpdateValues])

  const handleSubmit = async () => {
    try {
      setSubmitLoading(true)
      const newObject = await createObject(type, objectData)
      messageApi.success('Object created successfully')
      return newObject
    } catch (err) {
      console.error(err)
      if (err.errorFields) {
        return
      }
      messageApi.error('Failed to create object')
      showError(
        `Failed to create object. Message: ${err.message}. Code: ${err.code}`,
        () => handleSubmit()
      )
    } finally {
      setSubmitLoading(false)
    }
  }

  return (
    <Form
      form={form}
      layout='vertical'
      style={style}
      onValuesChange={(values) => {
        setObjectData((prev) => ({ ...prev, ...values }))
      }}
    >
      {contextHolder}
      {children({
        submitLoading: submitLoading,
        handleSubmit,
        form,
        formValid,
        objectData,
        setObjectData
      })}
    </Form>
  )
}

NewObjectForm.propTypes = {
  type: PropTypes.string.isRequired,
  children: PropTypes.func.isRequired,
  style: PropTypes.object,
  defaultValues: PropTypes.object
}

export default NewObjectForm
