import React, { useState } from 'react'
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { MenuItem } from '@/proxy/menus/menu'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { MenuService } from '@/services/menu.service'
import navigationIcon from '@/proxy/menus/navigation-icon.config'
import { FaQuestionCircle } from 'react-icons/fa'
import {
  Button,
  Dialog,
  FormContainer,
  FormItem,
  Input,
  Switcher,
  Notification,
  toast,
  Select,
} from '@/components/ui'
import { Field, FieldProps, Form, Formik } from 'formik'
import { SelectBoxOption } from '@/types/shared'
import * as Yup from 'yup'
import { FaExternalLinkAlt, FaPlus, FaTrashAlt } from 'react-icons/fa'
import { MenuDto } from '@/proxy/menus/models'

interface MenuItemComponentProps {
  item: MenuItem
  isDesignMode: boolean
  depth: number
  children?: React.ReactNode
  isDragOverlay?: boolean
  refetch: () => void
  permissions: SelectBoxOption[]
}

export const MenuItemComponent: React.FC<MenuItemComponentProps> = ({
  item,
  isDesignMode,
  depth,
  children,
  isDragOverlay = false,
  refetch,
  permissions,
}) => {
  const { translate } = useLocalization()

  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
    id: item.id || '',
    data: {
      type: 'menu-item',
      item,
    },
    disabled: !isDesignMode,
  })

  const validationSchema = Yup.object().shape({
    code: Yup.string().required(),
    displayName: Yup.string().required(),
    order: Yup.number().required(),
    url: Yup.string().nullable(),
    icon: Yup.string().nullable(),
    cssClass: Yup.string().nullable(),
    requiredPermissionName: Yup.string().nullable(),
    target: Yup.string().nullable(),
    elementId: Yup.string().nullable(),
    isDisabled: Yup.boolean(),
  })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  }

  const [isExpanded, setIsExpanded] = useState(true)
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [modalMode, setModalMode] = useState<'create' | 'edit'>('create')

  const getCreateInitialValues = (): Partial<MenuDto> => ({
    code: '',
    displayName: '',
    order: (item.children?.length || 0) + 1,
    parentCode: item.code,
    url: '',
    icon: '',
    cssClass: '',
    requiredPermissionName: '',
    target: '',
    isDisabled: false,
    elementId: '',
  })

  const getEditInitialValues = (): Partial<MenuDto> => ({
    id: item.id,
    code: item.code || '',
    displayName: item.displayName || '',
    order: item.order,
    parentCode: item.parentCode || '',
    url: item.url || '',
    icon: item.icon || '',
    cssClass: item.cssClass || '',
    requiredPermissionName: item.requiredPermissionName || '',
    target: item.target || '',
    isDisabled: item.isDisabled ?? false,
    elementId: item.elementId || '',
  })

  const [formData, setFormData] = useState<Partial<MenuDto>>(getCreateInitialValues())

  const toggleExpanded = () => {
    if (!isDesignMode) setIsExpanded(!isExpanded)
  }

  const openCreateModal = () => {
    setModalMode('create')
    setFormData(getCreateInitialValues())
    setIsModalOpen(true)
  }

  const openEditModal = (event: React.MouseEvent) => {
    if (!isDesignMode) return
    event.stopPropagation()
    setModalMode('edit')
    setFormData(getEditInitialValues())
    setIsModalOpen(true)
  }

  const handleDelete = async () => {
    const confirmed = window.confirm(`Delete "${item.displayName}"?`)
    if (!confirmed) return
    const menuService = new MenuService()
    await menuService.delete(item.id!)
    refetch()
  }

  return (
    <div className="select-none">
      <div
        ref={setNodeRef}
        style={style}
        className={`
          flex items-center gap-1 p-1 rounded-lg transition-all duration-200 group min-h-[30px]
          ${isDesignMode ? 'cursor-move hover:bg-blue-50 dark:hover:bg-blue-900 border border-transparent hover:border-blue-200 dark:hover:border-blue-400' : 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800'}
          ${isDragOverlay ? 'shadow-lg bg-white dark:bg-gray-800 border border-blue-300 dark:border-blue-500 z-50' : ''}
          ${isDragging ? 'opacity-50' : ''}
          ${item.children && item.children.length > 0 ? 'bg-blue-50 dark:bg-blue-900' : depth === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50 dark:bg-gray-900'}
        `}
        {...(isDesignMode ? { ...attributes, ...listeners } : { onClick: toggleExpanded })}
      >
        {isDesignMode && (
          <div className="flex gap-2 items-center mr-2">
            <Button
              onClick={openCreateModal}
              title="New Item"
              size="xs"
              variant="plain"
              shape="circle"
              icon={
                <FaPlus
                  size={16}
                  className="text-green-600 hover:text-green-800 dark:text-green-400 dark:hover:text-green-300"
                />
              }
              className="!h-6 !w-6 !px-0"
            />
            <Button
              onClick={handleDelete}
              title="Delete Item"
              size="xs"
              variant="plain"
              shape="circle"
              icon={
                <FaTrashAlt
                  size={16}
                  className="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"
                />
              }
              className="!h-6 !w-6 !px-0"
            />
          </div>
        )}

        <div className="flex items-center gap-3 flex-1 min-w-0">
          <div className="flex-shrink-0 text-gray-600 dark:text-gray-300 text-xl">
            {navigationIcon[item.icon || ''] ? (
              React.createElement(navigationIcon[item.icon || ''], {
                className: 'text-gray-400 dark:text-gray-500',
              })
            ) : (
              <FaQuestionCircle className="text-gray-400 dark:text-gray-500" />
            )}
          </div>

          <Button
            type="button"
            onClick={openEditModal}
            variant="plain"
            shape="none"
            className={`
              !h-auto !justify-start !rounded-none !px-0 !py-0 truncate text-gray-800 dark:text-gray-100 leading-6 text-sm text-left hover:!bg-transparent active:!bg-transparent focus:!bg-transparent
              ${item.children && item.children.length > 0 ? 'font-semibold' : 'font-normal'}
              ${isDesignMode ? 'hover:text-blue-600 dark:hover:text-blue-400' : ''}
            `}
          >
            {translate('::' + item.displayName)}
          </Button>
        </div>

        <div className="flex items-center gap-2 flex-shrink-0">
          {isDesignMode && (
            <div className="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400">
              <span className="bg-gray-200 dark:bg-gray-700 px-2 py-1 rounded">#{item.order}</span>
            </div>
          )}

          {item.children && item.children.length > 0 && (
            <span className="text-xs text-gray-500 dark:text-gray-300 bg-blue-100 dark:bg-blue-900 px-2 py-1 rounded-full">
              {item.children.length}
            </span>
          )}
        </div>
      </div>

      {children && (!isDesignMode ? isExpanded : true) && <div className="mt-1">{children}</div>}

      {isModalOpen && (
        <Dialog
          isOpen={isModalOpen}
          onClose={() => setIsModalOpen(false)}
          onRequestClose={() => setIsModalOpen(false)}
          width={600}
        >
          <h5 className="mb-4 dark:text-gray-100">
            {modalMode === 'edit' ? translate('::Edit Menu Item') : translate('::New Item')}
          </h5>
          <Formik
            validationSchema={validationSchema}
            initialValues={formData}
            enableReinitialize
            onSubmit={async (values, { setSubmitting }) => {
              try {
                const menuService = new MenuService()
                if (modalMode === 'edit' && item.id) {
                  await menuService.update(item.id, values as MenuDto)
                } else {
                  await menuService.create(values as MenuDto)
                }
                toast.push(
                  <Notification title="Başarılı" type="success">
                    {modalMode === 'edit'
                      ? translate('::KayitGuncellendi')
                      : translate('::KayitEklendi')}
                  </Notification>,
                  { placement: 'top-end' },
                )
                setIsModalOpen(false)
                refetch()
              } catch (error) {
                toast.push(
                  <Notification title="Hata" type="danger">
                    {translate('::IslemBasarisiz')}
                  </Notification>,
                  { placement: 'top-end' },
                )
              } finally {
                setSubmitting(false)
              }
            }}
          >
            {({ values, isSubmitting }) => (
              <Form>
                <FormContainer>
                  <FormItem label="Code *" className="mb-2">
                    <Field
                      type="text"
                      name="code"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                      autoFocus
                    />
                  </FormItem>

                  <FormItem label="Display Name *" className="mb-2">
                    <Field
                      type="text"
                      name="displayName"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Order *" className="mb-2">
                    <Field
                      type="number"
                      name="order"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="URL" className="mb-2">
                    <Field
                      type="text"
                      name="url"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Icon" className="mb-2">
                    <Field
                      type="text"
                      name="icon"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Parent Code" className="mb-2">
                    <Input
                      disabled
                      value={values.parentCode || ''}
                      className="h-8 text-sm px-2 bg-gray-100 dark:bg-gray-800 dark:text-gray-300"
                    />
                  </FormItem>

                  <FormItem label="CSS Class" className="mb-2">
                    <Field
                      type="text"
                      name="cssClass"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Permission Name" className="mb-2">
                    <Field
                      type="text"
                      autoComplete="off"
                      name="requiredPermissionName"
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    >
                      {({ field, form }: FieldProps<SelectBoxOption>) => (
                        <Select
                          field={field}
                          form={form}
                          isClearable={true}
                          options={permissions}
                          value={permissions?.filter(
                            (option) => option.value === values.requiredPermissionName,
                          )}
                          onChange={(option) => form.setFieldValue(field.name, option?.value)}
                        />
                      )}
                    </Field>
                  </FormItem>

                  <FormItem label="Target" className="mb-2">
                    <Field
                      type="text"
                      name="target"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Element Id" className="mb-2">
                    <Field
                      type="text"
                      name="elementId"
                      component={Input}
                      className="h-8 text-sm px-2 dark:bg-gray-900 dark:text-gray-100"
                    />
                  </FormItem>

                  <FormItem label="Is Disabled" className="mb-2">
                    <Field name="isDisabled" component={Switcher} />
                  </FormItem>

                  <div className="flex justify-end gap-2 mt-4">
                    <Button variant="plain" size="sm" onClick={() => setIsModalOpen(false)}>
                      {translate('::Cancel')}
                    </Button>
                    <Button type="submit" variant="solid" size="sm" loading={isSubmitting}>
                      {modalMode === 'edit' ? translate('::Save') : translate('::Create')}
                    </Button>
                  </div>
                </FormContainer>
              </Form>
            )}
          </Formik>
        </Dialog>
      )}
    </div>
  )
}
