import React, { useState, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useEntities, EntityFieldType } from '../../contexts/EntityContext'
import {
  FaSave,
  FaArrowLeft,
  FaPlus,
  FaTrashAlt,
  FaDatabase,
  FaCog,
  FaTable,
  FaColumns,
} from 'react-icons/fa'
import { CustomEntityField } from '@/proxy/developerKit/models'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Formik, Form, Field, FieldProps, FieldArray } from 'formik'
import * as Yup from 'yup'
import { FormItem, Input, Select, Checkbox, FormContainer, Button } from '@/components/ui'
import { SelectBoxOption } from '@/shared/types'

// Validation schema
const validationSchema = Yup.object({
  name: Yup.string().required('Entity name is required'),
  displayName: Yup.string().required('Display name is required'),
  tableName: Yup.string().required('Table name is required'),
  description: Yup.string(),
  fields: Yup.array()
    .of(
      Yup.object({
        name: Yup.string().required('Field name is required'),
        type: Yup.string().required('Field type is required'),
        isRequired: Yup.boolean(),
        maxLength: Yup.number().nullable(),
        isUnique: Yup.boolean(),
        defaultValue: Yup.string().notRequired(),
        description: Yup.string().notRequired(),
        displayOrder: Yup.number().required(),
      }),
    )
    .min(1, 'At least one field is required'),
  isActive: Yup.boolean(),
  hasAuditFields: Yup.boolean(),
  hasSoftDelete: Yup.boolean(),
})

const EntityEditor: React.FC = () => {
  const { id } = useParams()
  const navigate = useNavigate()
  const { translate } = useLocalization()

  const { getEntity, addEntity, updateEntity } = useEntities()

  const isEditing = !!id

  // Initial values for Formik
  const [initialValues, setInitialValues] = useState({
    name: '',
    displayName: '',
    tableName: '',
    description: '',
    fields: [
      {
        id: crypto.randomUUID(),
        entityId: id || '',
        name: 'Name',
        type: 'string' as EntityFieldType,
        isRequired: true,
        maxLength: 100,
        description: 'Entity name',
        displayOrder: 1,
      },
    ] as CustomEntityField[],
    isActive: true,
    hasAuditFields: true,
    hasSoftDelete: true,
  })

  // Check if migration is applied to disable certain fields
  const isMigrationApplied = Boolean(
    isEditing && id && getEntity(id)?.migrationStatus === 'applied',
  )

  useEffect(() => {
    if (isEditing && id) {
      const entity = getEntity(id)
      if (entity) {
        // Ensure fields are sorted by displayOrder and normalized to sequential values
        const sortedFields = (entity.fields || [])
          .slice()
          .sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0))
          .map((f, idx) => ({ ...f, displayOrder: f.displayOrder ?? idx + 1 }))

        setInitialValues({
          name: entity.name,
          displayName: entity.displayName,
          tableName: entity.tableName,
          description: entity.description || '',
          fields: sortedFields,
          isActive: entity.isActive,
          hasAuditFields: entity.hasAuditFields,
          hasSoftDelete: entity.hasSoftDelete,
        })
      }
    }
  }, [id, isEditing, getEntity])

  const handleSubmit = async (values: typeof initialValues, { setSubmitting }: any) => {
    try {
      const sanitizedFields = values.fields.map((f) => {
        // send both `displayOrder` (frontend proxy) and `order` (backend DTO) to be safe
        const sanitized: any = {
          ...(f.id && isEditing ? { id: f.id } : {}),
          name: f.name.trim(),
          type: f.type,
          isRequired: f.isRequired,
          maxLength: f.maxLength,
          isUnique: f.isUnique || false,
          defaultValue: f.defaultValue,
          description: f.description,
          displayOrder: f.displayOrder,
          order: f.displayOrder,
        }

        return sanitized
      })

      const entityData = {
        name: values.name.trim(),
        displayName: values.displayName.trim(),
        tableName: values.tableName.trim(),
        description: values.description.trim(),
        fields: sanitizedFields,
        isActive: values.isActive,
        hasAuditFields: values.hasAuditFields,
        hasSoftDelete: values.hasSoftDelete,
      }

      if (isEditing && id) {
        await updateEntity(id, entityData)
      } else {
        await addEntity(entityData)
      }

      navigate(ROUTES_ENUM.protected.saas.developerKit.entities, { replace: true })
    } catch (error) {
      console.error('Error saving entity:', error)
      alert('Failed to save entity. Please try again.')
    } finally {
      setSubmitting(false)
    }
  }

  const fieldTypes = [
    { value: 'string', label: 'String' },
    { value: 'number', label: 'Number' },
    { value: 'decimal', label: 'Decimal' },
    { value: 'boolean', label: 'Boolean' },
    { value: 'date', label: 'Date' },
    { value: 'guid', label: 'Guid' },
  ]

  return (
    <Formik
      enableReinitialize
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ values, touched, errors, isSubmitting, setFieldValue, submitForm, isValid }) => (
        <>
          {/* Enhanced Header */}
          <div className="bg-white shadow border-b border-slate-200 sticky top-0 z-10">
            <div className="px-4 py-3">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <button
                    type="button"
                    onClick={() => navigate(ROUTES_ENUM.protected.saas.developerKit.entities)}
                    className="flex items-center gap-2 text-slate-600 hover:text-blue-600 hover:bg-blue-50 px-3 py-2 rounded-lg transition-all duration-200"
                  >
                    <FaArrowLeft className="w-4 h-4" />
                    <span className="text-sm">
                      {translate('::App.DeveloperKit.EntityEditor.Back')}
                    </span>
                  </button>
                  <div className="h-6 w-px bg-slate-300"></div>
                  <div className="flex items-center gap-3">
                    <div className="bg-gradient-to-r from-green-500 to-blue-600 p-1 rounded">
                      <FaDatabase className="w-5 h-5 text-white" />
                    </div>
                    <div>
                      <h1 className="text-xl font-bold text-slate-900">
                        {isEditing
                          ? `${translate('::App.DeveloperKit.EntityEditor.Title.Edit')} - ${values.name || initialValues.name || 'Entity'}`
                          : translate('::App.DeveloperKit.Entity.CreateEntity')}
                      </h1>
                      <p className="text-sm text-slate-600">
                        {isEditing ? 'Modify your entity' : 'Create a new entity'}
                      </p>
                    </div>
                  </div>
                </div>

                {/* Save Button in Header */}
                <div className="flex items-center gap-2">
                  <button
                    type="button"
                    onClick={submitForm}
                    disabled={isSubmitting || !isValid}
                    className="flex items-center gap-1 bg-gradient-to-r from-green-600 to-green-700 hover:from-green-700 hover:to-green-800 text-white font-semibold px-2 py-1.5 rounded shadow transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed text-sm"
                  >
                    <FaSave className="w-3 h-3" />
                    {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
                  </button>
                </div>
              </div>
            </div>
          </div>

          <Form className="grid grid-cols-1 lg:grid-cols-4 gap-4 pt-2">
            {/* Basic Entity Information */}
            <div className="space-y-4 col-span-1">
              <div className="bg-white rounded-lg shadow-sm border border-slate-200 p-3">
                <div className="flex items-center gap-2 mb-4">
                  <div className="bg-blue-100 p-1.5 rounded-lg">
                    <FaCog className="w-4 h-4 text-blue-600" />
                  </div>
                  <h2 className="text-sm font-semibold text-slate-900">Entity Settings</h2>
                </div>

                <FormContainer size="sm">
                  <FormItem
                    label={translate('::App.DeveloperKit.EntityEditor.EntityName')}
                    invalid={!!(errors.name && touched.name)}
                    errorMessage={errors.name as string}
                  >
                    <Field name="name">
                      {({ field }: FieldProps) => (
                        <Input
                          {...field}
                          onBlur={(e) => {
                            field.onBlur(e)
                            if (!values.tableName) {
                              setFieldValue('tableName', values.name + 's')
                            }
                            if (!values.displayName) {
                              setFieldValue('displayName', values.name)
                            }
                          }}
                          disabled={isMigrationApplied}
                          placeholder="e.g., Product, User, Order"
                          className="px-2 py-1.5 bg-slate-50 focus:bg-white transition-all duration-200 text-sm h-7"
                        />
                      )}
                    </Field>
                  </FormItem>

                  <FormItem
                    label={translate('::App.DeveloperKit.EntityEditor.DisplayName')}
                    invalid={!!(errors.displayName && touched.displayName)}
                    errorMessage={errors.displayName as string}
                  >
                    <Field
                      name="displayName"
                      component={Input}
                      placeholder="e.g., Product, User, Order"
                    />
                  </FormItem>

                  <FormItem
                    label={translate('::App.DeveloperKit.EntityEditor.TableName')}
                    invalid={!!(errors.tableName && touched.tableName)}
                    errorMessage={errors.tableName as string}
                  >
                    <Field
                      name="tableName"
                      component={Input}
                      disabled={isMigrationApplied}
                      placeholder="e.g., Products, Users, Orders"
                    />
                  </FormItem>

                  <FormItem
                    label={translate('::App.DeveloperKit.EntityEditor.Description')}
                    invalid={!!(errors.description && touched.description)}
                    errorMessage={errors.description as string}
                  >
                    <Field
                      name="description"
                      component={Input}
                      placeholder="Brief description of this entity"
                    />
                  </FormItem>

                  <FormItem label={translate('::App.DeveloperKit.ComponentEditor.Active')}>
                    <Field name="isActive" component={Checkbox} />
                  </FormItem>

                  <FormItem label={translate('::App.DeveloperKit.EntityEditor.Audit')}>
                    <Field name="hasAuditFields" component={Checkbox} />
                  </FormItem>

                  <FormItem label={translate('::App.DeveloperKit.EntityEditor.SoftDelete')}>
                    <Field name="hasSoftDelete" component={Checkbox} />
                  </FormItem>
                </FormContainer>
              </div>
            </div>

            {/* Fields Section */}
            <div className="space-y-4 col-span-3">
              <div className="bg-white rounded-lg shadow-sm border border-slate-200 p-3">
                <FormContainer size="sm">
                  <FieldArray name="fields">
                    {({ push, remove }) => (
                      <>
                        <div className="flex items-center justify-between mb-2">
                          <div className="flex items-center gap-1">
                            <div className="bg-green-100 p-1.5 rounded">
                              <FaColumns className="w-4 h-4 text-green-600" />
                            </div>
                            <h2 className="text-sm font-semibold text-slate-900">
                              {translate('::App.DeveloperKit.EntityEditor.Fields')}
                            </h2>
                          </div>
                          <button
                            type="button"
                            onClick={() =>
                              push({
                                id: crypto.randomUUID(),
                                entityId: id || '',
                                name: '',
                                type: 'string',
                                isRequired: false,
                                description: '',
                                // Assign next sequential displayOrder
                                displayOrder: (values.fields?.length ?? 0) + 1,
                              })
                            }
                            className="flex items-center gap-1 bg-gradient-to-r from-blue-600 to-blue-700 text-white px-2 py-1.5 rounded hover:from-blue-700 hover:to-blue-800 transition-all duration-200 text-sm"
                          >
                            <FaPlus className="w-2.5 h-2.5" />
                            {translate('::App.DeveloperKit.EntityEditor.AddField')}
                          </button>
                        </div>

                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-2 mb-2">
                          <div className="col-span-1">Order *</div>

                          <div className="col-span-2 font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.FieldName')} *
                          </div>

                          <div className="col-span-1 font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.Type')} *
                          </div>

                          <div className="col-span-2 font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.DefaultValue')}
                          </div>

                          <div className="font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.MaxLength')}
                          </div>

                          <div className="col-span-2 font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.Description')}
                          </div>

                          <div className="items-center font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.Required')}
                          </div>

                          <div className="items-center font-bold">
                            {translate('::App.DeveloperKit.EntityEditor.Unique')}
                          </div>
                        </div>

                        {values.fields.map((field, index) => (
                          <div key={field.id || `new-${index}`}>
                            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-2">
                              <FormItem className="col-span-1">
                                <Field
                                  type="number"
                                  name={`fields.${index}.displayOrder`}
                                  component={Input}
                                />
                              </FormItem>

                              <FormItem
                                invalid={
                                  !!(
                                    errors.fields &&
                                    (errors.fields as any)[index]?.name &&
                                    touched.fields &&
                                    (touched.fields as any)[index]?.name
                                  )
                                }
                                errorMessage={(errors.fields as any)?.[index]?.name as string}
                                className="col-span-2"
                              >
                                <Field
                                  name={`fields.${index}.name`}
                                  component={Input}
                                  placeholder="e.g., Name, Email, Age"
                                />
                              </FormItem>

                              <FormItem
                                invalid={
                                  !!(
                                    errors.fields &&
                                    (errors.fields as any)[index]?.type &&
                                    touched.fields &&
                                    (touched.fields as any)[index]?.type
                                  )
                                }
                                errorMessage={(errors.fields as any)?.[index]?.type as string}
                                className="col-span-1"
                              >
                                <Field name={`fields.${index}.type`}>
                                  {({ field, form }: FieldProps<SelectBoxOption>) => (
                                    <Select
                                      field={field}
                                      form={form}
                                      options={fieldTypes.map((type) => ({
                                        value: type.value,
                                        label: type.label,
                                      }))}
                                      value={fieldTypes
                                        .map((type) => ({ value: type.value, label: type.label }))
                                        .filter((option) => option.value === field.value)}
                                      onChange={(option) =>
                                        form.setFieldValue(field.name, option?.value)
                                      }
                                    />
                                  )}
                                </Field>
                              </FormItem>

                              <FormItem
                                invalid={
                                  !!(
                                    errors.fields &&
                                    (errors.fields as any)[index]?.defaultValue &&
                                    touched.fields &&
                                    (touched.fields as any)[index]?.defaultValue
                                  )
                                }
                                errorMessage={
                                  (errors.fields as any)?.[index]?.defaultValue as string
                                }
                                className="col-span-2"
                              >
                                <Field
                                  name={`fields.${index}.defaultValue`}
                                  component={Input}
                                  placeholder="Optional default value"
                                />
                              </FormItem>

                              <FormItem
                                invalid={
                                  !!(
                                    errors.fields &&
                                    (errors.fields as any)[index]?.maxLength &&
                                    touched.fields &&
                                    (touched.fields as any)[index]?.maxLength
                                  )
                                }
                                errorMessage={(errors.fields as any)?.[index]?.maxLength as string}
                              >
                                <Field
                                  name={`fields.${index}.maxLength`}
                                  component={Input}
                                  type="number"
                                  placeholder="e.g., 100"
                                  disabled={field.type !== 'string'}
                                />
                              </FormItem>

                              <FormItem
                                invalid={
                                  !!(
                                    errors.fields &&
                                    (errors.fields as any)[index]?.description &&
                                    touched.fields &&
                                    (touched.fields as any)[index]?.description
                                  )
                                }
                                errorMessage={
                                  (errors.fields as any)?.[index]?.description as string
                                }
                                className="col-span-2"
                              >
                                <Field
                                  name={`fields.${index}.description`}
                                  component={Input}
                                  placeholder="Field description"
                                />
                              </FormItem>

                              <FormItem className="items-center">
                                <Field name={`fields.${index}.isRequired`} component={Checkbox} />
                              </FormItem>

                              <FormItem className="items-center">
                                <Field name={`fields.${index}.isUnique`} component={Checkbox} />
                              </FormItem>

                              <Button
                                size="xs"
                                onClick={() => {
                                  remove(index)
                                  const newFields = values.fields ? [...values.fields] : []
                                  newFields.splice(index, 1)
                                  newFields.forEach((f, i) => {
                                    f.displayOrder = i + 1
                                  })
                                  setFieldValue('fields', newFields)
                                }}
                                className="!px-0 !py-0 !border-0 text-red-600 hover:text-red-800 rounded transition-all duration-200"
                                title="Remove field"
                              >
                                <FaTrashAlt className="w-5 h-5" />
                              </Button>
                            </div>
                          </div>
                        ))}

                        {values.fields.length === 0 && (
                          <div className="text-center py-4 bg-slate-50 rounded border-2 border-dashed border-slate-300">
                            <FaTable className="w-8 h-8 mx-auto mb-2 text-slate-400" />
                            <h3 className="text-sm font-medium text-slate-600 mb-1">
                              {translate('::App.DeveloperKit.EntityEditor.NoFields')}
                            </h3>
                            <p className="text-sm text-slate-500">
                              {translate('::App.DeveloperKit.EntityEditor.NoFieldsDescription')}
                            </p>
                          </div>
                        )}
                      </>
                    )}
                  </FieldArray>
                </FormContainer>
              </div>
            </div>
          </Form>
        </>
      )}
    </Formik>
  )
}

export default EntityEditor
