import { ElementConstructor } from '@/component/TemplateManager/ElementConstructor'
import { useTemplateContext } from '@/entity/template/model/TemplateContext'
import { useDelayedSave } from '@/hook/useDelayedSave'
import { useSafeNavigation } from '@/hook/useSafeNavigation'
import { FormLayoutSettings, Template, TemplateElement } from '@/type/template'
import { ArrowLeft, FileText, Loader2, Settings, Wrench } from 'lucide-react'
import { FC, useCallback, useEffect, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { Button } from 'shared/ui/button'

export const ElementsCreation: FC = () => {
  const navigate = useNavigate()
  const { templateId } = useParams<{ templateId: string }>()
  const { templates, updateTemplate, isLoading, error } = useTemplateContext()
  const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(
    null
  )
  const [isInitialized, setIsInitialized] = useState(false)

  // Автоматически выбираем шаблон, если передан templateId
  useEffect(() => {
    if (templateId && !isInitialized) {
      const template = templates.find(t => t.id === templateId)
      if (template) {
        setSelectedTemplate(template)
        setIsInitialized(true)
      } else if (!isLoading && templates.length > 0) {
        // Если шаблон не найден после загрузки, перенаправляем на страницу со списком шаблонов
        navigate('/templates', { replace: true })
      }
    }
  }, [templateId, templates, navigate, isLoading, isInitialized])

  // Функция для сохранения шаблона в БД
  const saveTemplate = useCallback(
    async (template: Template) => {
      await updateTemplate(template)
    },
    [updateTemplate]
  )

  // Хук для отложенного сохранения
  const {
    hasUnsavedChanges,
    isSaving,
    lastSaveError,
    updateData,
    manualSave,
    clearError,
  } = useDelayedSave({
    onSave: saveTemplate,
    delay: 2000, // 2 секунды задержки
  })

  // Хук для безопасной навигации
  const { safeNavigate, isNavigating } = useSafeNavigation({
    onBeforeNavigate: manualSave,
    hasUnsavedChanges,
    isSaving,
  })

  const handleElementAdd = async (element: TemplateElement) => {
    if (!selectedTemplate) {
      return
    }

    const updatedTemplate = {
      ...selectedTemplate,
      elements: [...selectedTemplate.elements, element],
      updatedAt: new Date(),
    }

    setSelectedTemplate(updatedTemplate)
    updateData(updatedTemplate)
  }

  const handleElementUpdate = async (
    elementId: string,
    updates: Partial<TemplateElement>
  ) => {
    if (!selectedTemplate) return

    const updatedTemplate = {
      ...selectedTemplate,
      elements: selectedTemplate.elements.map(el =>
        el.id === elementId
          ? {
              ...el,
              // Обновляем только определённые ключи, чтобы не затирать существующие значения `undefined`
              ...Object.fromEntries(
                Object.entries(updates).filter(([, v]) => v !== undefined)
              ),
            }
          : el
      ),
      updatedAt: new Date(),
    }

    setSelectedTemplate(updatedTemplate)
    updateData(updatedTemplate)
  }

  const handleElementDelete = async (elementId: string) => {
    if (!selectedTemplate) return

    const updatedTemplate = {
      ...selectedTemplate,
      elements: selectedTemplate.elements.filter(el => el.id !== elementId),
      updatedAt: new Date(),
    }

    setSelectedTemplate(updatedTemplate)
    updateData(updatedTemplate)
  }

  const handleLayoutSettingsChange = async (
    layoutSettings: FormLayoutSettings
  ) => {
    if (!selectedTemplate) return

    const updatedTemplate = {
      ...selectedTemplate,
      layoutSettings,
      updatedAt: new Date(),
    }

    setSelectedTemplate(updatedTemplate)
    updateData(updatedTemplate)
  }

  // if (isLoading) {
  //   return (
  //     <div className="flex h-screen items-center justify-center">
  //       <div className="text-center">
  //         <div className="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
  //         <p className="text-sm text-muted-foreground">Загрузка шаблонов...</p>
  //       </div>
  //     </div>
  //   )
  // }

  if (error) {
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="text-center">
          <h3 className="mb-2 text-lg font-medium text-destructive">
            Ошибка загрузки
          </h3>
          <p className="mb-4 text-sm text-muted-foreground">{error.message}</p>
          <Button onClick={() => window.location.reload()}>
            Обновить страницу
          </Button>
        </div>
      </div>
    )
  }

  if (!selectedTemplate) {
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="text-center">
          <Wrench className="mx-auto mb-4 h-16 w-16 text-muted-foreground" />
          <h3 className="mb-2 text-lg font-medium">Шаблон не найден</h3>
          <p className="mb-4 text-sm text-muted-foreground">
            Перейдите к списку шаблонов для выбора
          </p>
          <Button onClick={() => navigate('/templates')}>
            К списку шаблонов
          </Button>
        </div>
      </div>
    )
  }

  return (
    <div className="flex h-screen flex-col">
      <div className="flex-shrink-0 border-b bg-card px-4 py-2">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Button
              variant="ghost"
              size="icon"
              onClick={() => safeNavigate('/templates')}
              disabled={isNavigating || isSaving}
            >
              {isNavigating ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <ArrowLeft className="h-4 w-4" />
              )}
            </Button>
            <div className="flex items-center space-x-2">
              <Wrench className="h-5 w-5" />
              <h1 className="text-lg font-semibold">Редактор интерфейса</h1>
              <span className="text-sm text-muted-foreground">—</span>
              <span className="text-sm text-muted-foreground">
                {selectedTemplate.name}
              </span>
            </div>
          </div>
          <div className="flex gap-2">
            <Button
              variant="link"
              size="sm"
              onClick={() =>
                safeNavigate(`/templates/${selectedTemplate.id}/edit`)
              }
              disabled={isNavigating || isSaving}
              className="flex items-center gap-1 hover:bg-muted"
            >
              {isNavigating ? (
                <>
                  <Loader2 className="h-4 w-4 animate-spin" />
                  <span className="text-sm">Сохранение...</span>
                </>
              ) : (
                <>
                  <Settings className="h-4 w-4" />
                  <span className="text-sm">Настройки шаблона</span>
                </>
              )}
            </Button>
            <Button
              variant="link"
              size="sm"
              onClick={() =>
                safeNavigate(`/templates/${selectedTemplate.id}/protocols`)
              }
              disabled={isNavigating || isSaving}
              className="flex items-center gap-1 hover:bg-muted"
            >
              {isNavigating ? (
                <>
                  <Loader2 className="h-4 w-4 animate-spin" />
                  <span className="text-sm">Сохранение...</span>
                </>
              ) : (
                <>
                  <FileText className="h-4 w-4" />
                  <span className="text-sm">Создать протокол</span>
                </>
              )}
            </Button>
          </div>
        </div>
      </div>
      <div className="flex-1 overflow-hidden">
        <ElementConstructor
          template={selectedTemplate}
          onElementAdd={handleElementAdd}
          onElementUpdate={handleElementUpdate}
          onElementDelete={handleElementDelete}
          onLayoutSettingsChange={handleLayoutSettingsChange}
          disabled={false}
          hasUnsavedChanges={hasUnsavedChanges}
          isSaving={isSaving}
          lastSaveError={lastSaveError}
          onManualSave={manualSave}
          onClearError={clearError}
        />
      </div>
    </div>
  )
}
