import React, { useState, useEffect } from 'react'
import { useComponents } from '../../contexts/ComponentContext'
import { FaRegSave, FaSync, FaCog } from 'react-icons/fa'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Formik, Form, Field } from 'formik'
import * as Yup from 'yup'
import { Button, Checkbox, FormContainer, FormItem, Input } from '@/components/ui'
import Dialog from '@/components/ui/Dialog'
import { generateDesignerCode } from '@/components/visualDesigner/codeGenerator'
import {
  createDesignerId,
  createEmptyDesignerDocument,
  type DesignerDocument,
} from '@/components/visualDesigner/types'

// Validation schema
const validationSchema = Yup.object({
  name: Yup.string().required(),
  routePath: Yup.string().required().matches(/^\//, 'Route path must start with /'),
  description: Yup.string(),
  dependencies: Yup.array().of(Yup.string()),
  isActive: Yup.boolean(),
})

interface ComponentEditorProps {
  componentId?: string | null
  onClose?: () => void
  onSaved?: () => void | Promise<void>
}

const ComponentEditor: React.FC<ComponentEditorProps> = ({
  componentId,
  onClose,
  onSaved,
}) => {
  const id = componentId || undefined
  const { translate } = useLocalization()

  const { getComponent, addComponent, updateComponent, refreshComponent } = useComponents()

  const [isLoaded, setIsLoaded] = useState(false)

  const isEditing = !!id

  // Initial values for Formik
  const [initialValues, setInitialValues] = useState({
    name: '',
    routePath: '',
    description: '',
    dependencies: [] as string[],
    isActive: true,
  })

  // Load existing component data - sadece edit modunda
  useEffect(() => {
    if (isEditing && id && !isLoaded) {
      let cancelled = false

      void refreshComponent(id).then((freshComponent) => {
        if (cancelled) return
        const component = freshComponent
        if (!component) {
          setIsLoaded(true)
          return
        }

        // Parse dependencies from JSON string
        let deps: string[] = []
        try {
          deps = component.dependencies ? JSON.parse(component.dependencies) : []
          deps = Array.isArray(deps) ? deps : []
        } catch {
          deps = []
        }

        const values = {
          name: component.name,
          routePath: component.routePath,
          description: component.description || '',
          dependencies: deps,
          isActive: component.isActive,
        }

        setInitialValues(values)
        setIsLoaded(true)
      })

      return () => {
        cancelled = true
      }
    } else if (!isEditing && !isLoaded) {
      // Yeni komponent için boş başla - TEMPLATE YOK
      setIsLoaded(true)
    }
  }, [id, isEditing, isLoaded, refreshComponent])

  const createDefaultVisualDocument = (componentName: string): DesignerDocument => {
    const document = createEmptyDesignerDocument('visual')
    document.nodes = [
      {
        id: createDesignerId(),
        type: 'span',
        kind: 'html',
        props: { children: componentName.trim() },
        events: {},
        bindings: {},
        children: [],
      },
    ]
    return document
  }

  const handleSubmit = async (values: typeof initialValues, { setSubmitting }: any) => {
    if (!values.name.trim()) {
      alert('Please enter a component name')
      setSubmitting(false)
      return
    }

    try {
      const existingComponent = isEditing && id ? getComponent(id) : undefined
      const defaultDocument = createDefaultVisualDocument(values.name)
      const componentData = {
        name: values.name.trim(),
        routePath: values.routePath.trim(),
        description: values.description.trim(),
        dependencies: JSON.stringify(values.dependencies), // Serialize dependencies to JSON string
        code: existingComponent
          ? existingComponent.code
          : generateDesignerCode(values.name, defaultDocument),
        props: existingComponent
          ? existingComponent.props
          : JSON.stringify({ visualDesigner: defaultDocument }),
        isActive: values.isActive,
      }

      if (isEditing && id) {
        await updateComponent(id, componentData)
      } else {
        await addComponent(componentData)
      }

      await onSaved?.()
      onClose?.()
    } catch (error) {
      console.error('Error saving component:', error)
      alert('Failed to save component. Please try again.')
    } finally {
      setSubmitting(false)
    }
  }

  // Loading state - komponent yüklenene kadar bekle
  if (isEditing && !isLoaded) {
    return (
      <div className="flex min-h-72 items-center justify-center">
        <div className="text-center">
          <FaSync className="w-8 h-8 text-blue-500 animate-spin mx-auto mb-3" />
          <p className="text-slate-600">{translate('::App.Platform.LoadingWithThreeDot')}</p>
        </div>
      </div>
    )
  }

  return (
    <Formik
      enableReinitialize
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ values, touched, errors, isSubmitting, setFieldValue, submitForm, isValid }) => {
        return (
          <>
            <Form className="pb-3 pt-8">
              <div className="space-y-3">
                <div className="bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-slate-200 dark:border-gray-700 p-3">
                  <div className="flex items-center gap-2 mb-3">
                    <div className="bg-blue-100 dark:bg-blue-900/20 p-1.5 rounded-lg">
                      <FaCog className="w-4 h-4 text-blue-600 dark:text-blue-400" />
                    </div>
                    <h2 className="text-base font-semibold text-slate-900 dark:text-gray-100">
                      Component Settings
                    </h2>
                  </div>

                  <FormContainer size="sm">
                    <FormItem
                      label={translate('::App.DeveloperKitComponentEditor.ComponentName')}
                      invalid={!!(errors.name && touched.name)}
                      errorMessage={errors.name as string}
                    >
                      <Field
                        autoFocus
                        name="name"
                        type="text"
                        component={Input}
                        placeholder="e.g., Button, Card, Modal"
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                          setFieldValue('name', e.target.value)
                        }}
                      />
                    </FormItem>

                    <FormItem
                      label="Route Path"
                      invalid={!!(errors.routePath && touched.routePath)}
                      errorMessage={errors.routePath as string}
                    >
                      <Field
                        name="routePath"
                        type="text"
                        component={Input}
                        placeholder="e.g., /roles or /admin/reports"
                      />
                    </FormItem>

                    <FormItem
                      label={translate('::App.Listform.ListformField.Description')}
                      invalid={!!(errors.description && touched.description)}
                      errorMessage={errors.description as string}
                    >
                      <Field
                        name="description"
                        type="text"
                        component={Input}
                        placeholder="Brief description of the component"
                        textArea={true}
                      />
                    </FormItem>

                    <FormItem
                      label={translate('::App.DeveloperKitComponentEditor.Dependencies')}
                      invalid={!!(errors.dependencies && touched.dependencies)}
                      errorMessage={errors.dependencies as string}
                    >
                      <Field name="dependencies">
                        {() => (
                          <Input
                            type="text"
                            value={(values.dependencies || []).join(', ')}
                            placeholder="MyComponent, AnotherComponent, etc."
                            onChange={(e) =>
                              setFieldValue(
                                'dependencies',
                                e.target.value
                                  .split(',')
                                  .map((s) => s.trim())
                                  .filter(Boolean),
                              )
                            }
                          />
                        )}
                      </Field>
                    </FormItem>

                    <FormItem label={translate('::App.Listform.ListformField.IsActive')}>
                      <Field name="isActive" component={Checkbox} />
                    </FormItem>
                  </FormContainer>
                </div>
              </div>
            </Form>
            <Dialog.Footer className="flex flex-col items-stretch gap-2 border-t border-slate-200 pt-3 dark:border-slate-700">
              <div className="flex items-center justify-end gap-2">
                <Button type="button" size="sm" disabled={isSubmitting} onClick={onClose}>
                  {translate('::App.Platform.Cancel')}
                </Button>
                <Button
                  type="button"
                  variant="solid"
                  size="sm"
                  disabled={isSubmitting || !values.name.trim() || !isValid}
                  className="flex items-center gap-2"
                  onClick={submitForm}
                >
                  <FaRegSave className="h-4 w-4" />
                  {isSubmitting ? translate('::App.Platform.Saving') : translate('::App.Platform.Save')}
                </Button>
              </div>
            </Dialog.Footer>
          </>
        )
      }}
    </Formik>
  )
}

export default ComponentEditor
