'use client'

import { useCallback, useEffect, useRef, useState } from 'react'
import {
  DndContext,
  closestCenter,
  PointerSensor,
  TouchSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  SortableContext,
  rectSortingStrategy,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { GripVertical, X, Plus, RotateCcw, Check, LayoutGrid, Eye, EyeOff } from 'lucide-react'
import { useLanguage } from '@/lib/i18n'
import {
  getDefaultDashboardLayout,
  resetDashboardLayout,
  DASHBOARD_CATEGORY_ORDER,
  DASHBOARD_WIDGET_META,
  catalogByCategory,
  hiddenWidgetIds,
  isWidgetVisible,
  normalizeDashboardLayout,
  reorderWidgets,
  setWidgetVisibility,
  visibleWidgetsInZone,
  type DashboardLayout,
  type DashboardWidgetId,
  type DashboardWidgetPlacement,
  type DashboardWidgetZone,
} from '@/lib/dashboard/layout'
import { toast } from 'sonner'

interface DashboardWidgetGridProps {
  renderWidget: (id: DashboardWidgetId) => React.ReactNode
  isWidgetEmpty?: (id: DashboardWidgetId) => boolean
}

function SortableWidget({
  placement,
  editMode,
  onHide,
  children,
}: {
  placement: DashboardWidgetPlacement
  editMode: boolean
  onHide: (id: DashboardWidgetId) => void
  children: React.ReactNode
}) {
  const { t } = useLanguage()
  const meta = DASHBOARD_WIDGET_META[placement.id]
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: placement.id, disabled: !editMode })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    zIndex: isDragging ? 20 : undefined,
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`relative w-full ${
        isDragging ? 'opacity-90 scale-[1.01]' : ''
      } ${editMode ? 'ring-2 ring-brand-accent/25 ring-offset-2 ring-offset-[#F9F8F6] dark:ring-offset-[#0D0D0D] rounded-2xl' : ''}`}
    >
      {editMode && (
        <div className="absolute top-2 end-2 z-20 flex items-center gap-1">
          <button
            type="button"
            className="p-1.5 rounded-lg bg-white/95 dark:bg-zinc-900/95 border border-border/40 shadow-sm cursor-grab active:cursor-grabbing text-concrete hover:text-ink"
            aria-label={t('homeDashboard.widgetDrag')}
            {...attributes}
            {...listeners}
          >
            <GripVertical size={12} />
          </button>
          {!meta.required && (
            <button
              type="button"
              onClick={() => onHide(placement.id)}
              className="p-1.5 rounded-lg bg-white/95 dark:bg-zinc-900/95 border border-border/40 shadow-sm text-concrete hover:text-rose-500"
              aria-label={t('homeDashboard.widgetHide')}
            >
              <X size={12} />
            </button>
          )}
        </div>
      )}
      {children}
    </div>
  )
}

function ZoneColumn({
  zone,
  placements,
  editMode,
  onHide,
  renderWidget,
}: {
  zone: DashboardWidgetZone
  placements: DashboardWidgetPlacement[]
  editMode: boolean
  onHide: (id: DashboardWidgetId) => void
  renderWidget: (id: DashboardWidgetId) => React.ReactNode
}) {
  if (placements.length === 0) return null

  return (
    <SortableContext items={placements.map(w => w.id)} strategy={verticalListSortingStrategy}>
      <div className="flex flex-col gap-4">
        {placements.map(placement => (
          <SortableWidget
            key={placement.id}
            placement={placement}
            editMode={editMode}
            onHide={onHide}
          >
            {renderWidget(placement.id)}
          </SortableWidget>
        ))}
      </div>
    </SortableContext>
  )
}

export function DashboardWidgetGrid({ renderWidget, isWidgetEmpty }: DashboardWidgetGridProps) {
  const { t } = useLanguage()
  const [layout, setLayout] = useState<DashboardLayout>(() => getDefaultDashboardLayout())
  const [editMode, setEditMode] = useState(false)
  const [catalogOpen, setCatalogOpen] = useState(false)
  const [loaded, setLoaded] = useState(false)
  const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null)

  useEffect(() => {
    fetch('/api/dashboard/layout', { cache: 'no-store' })
      .then(r => r.ok ? r.json() : null)
      .then(json => {
        if (json?.layout) {
          const normalized = normalizeDashboardLayout(json.layout)
          setLayout(normalized)
          const incomingVersion = typeof (json.layout as { version?: number })?.version === 'number'
            ? (json.layout as { version: number }).version
            : 0
          if (incomingVersion < normalized.version) {
            fetch('/api/dashboard/layout', {
              method: 'PUT',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ layout: normalized }),
            }).catch(() => {})
          }
        }
      })
      .catch(() => {})
      .finally(() => setLoaded(true))
  }, [])

  const persistLayout = useCallback((next: DashboardLayout, immediate = false) => {
    if (saveTimer.current) clearTimeout(saveTimer.current)
    const save = () => {
      fetch('/api/dashboard/layout', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ layout: next }),
      }).catch(() => {})
    }
    if (immediate) save()
    else saveTimer.current = setTimeout(save, 600)
  }, [])

  const applyLayout = useCallback((next: DashboardLayout, immediate = false) => {
    const normalized = normalizeDashboardLayout(next)
    setLayout(normalized)
    persistLayout(normalized, immediate)
  }, [persistLayout])

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
    useSensor(TouchSensor, { activationConstraint: { delay: 180, tolerance: 8 } }),
  )

  const handleDragEnd = useCallback((event: DragEndEvent) => {
    const { active, over } = event
    if (!over || active.id === over.id) return
    applyLayout(reorderWidgets(layout, active.id as DashboardWidgetId, over.id as DashboardWidgetId))
  }, [applyLayout, layout])

  const handleHide = useCallback((id: DashboardWidgetId) => {
    applyLayout(setWidgetVisibility(layout, id, false))
  }, [applyLayout, layout])

  const handleToggle = useCallback((id: DashboardWidgetId) => {
    const visible = isWidgetVisible(layout, id)
    if (visible) {
      applyLayout(setWidgetVisibility(layout, id, false))
    } else {
      const maxOrder = Math.max(...layout.widgets.map(w => w.order), 0)
      applyLayout({
        ...layout,
        widgets: layout.widgets.map(w =>
          w.id === id ? { ...w, visible: true, order: maxOrder + 1 } : w,
        ),
      })
    }
  }, [applyLayout, layout])

  const handleReset = useCallback(() => {
    const fresh = resetDashboardLayout()
    setLayout(fresh)
    persistLayout(fresh, true)
    setCatalogOpen(false)
    toast.success(t('homeDashboard.widgetResetDone'))
  }, [persistLayout, t])

  const fullWidgets = visibleWidgetsInZone(layout, 'full')
    .filter(w => editMode || !isWidgetEmpty?.(w.id))
  const mainWidgets = visibleWidgetsInZone(layout, 'main')
    .filter(w => editMode || !isWidgetEmpty?.(w.id))
  const sideWidgets = visibleWidgetsInZone(layout, 'side')
    .filter(w => editMode || !isWidgetEmpty?.(w.id))
  const hidden = hiddenWidgetIds(layout)
  const catalog = catalogByCategory(layout)
  const hasVisibleWidgets = fullWidgets.length + mainWidgets.length + sideWidgets.length > 0

  return (
    <>
      <div className="space-y-4">
        {loaded ? (
          hasVisibleWidgets ? (
          <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
            {fullWidgets.length > 0 && (
              <SortableContext items={fullWidgets.map(w => w.id)} strategy={rectSortingStrategy}>
                <div className="flex flex-col gap-4">
                  {fullWidgets.map(placement => (
                    <SortableWidget
                      key={placement.id}
                      placement={placement}
                      editMode={editMode}
                      onHide={handleHide}
                    >
                      {renderWidget(placement.id)}
                    </SortableWidget>
                  ))}
                </div>
              </SortableContext>
            )}

            {(mainWidgets.length > 0 || sideWidgets.length > 0) && (
              <div className="grid grid-cols-12 gap-4 items-start">
                {mainWidgets.length > 0 && (
                  <div className="col-span-12 lg:col-span-8">
                    <ZoneColumn
                      zone="main"
                      placements={mainWidgets}
                      editMode={editMode}
                      onHide={handleHide}
                      renderWidget={renderWidget}
                    />
                  </div>
                )}
                {sideWidgets.length > 0 && (
                  <div className="col-span-12 lg:col-span-4">
                    <ZoneColumn
                      zone="side"
                      placements={sideWidgets}
                      editMode={editMode}
                      onHide={handleHide}
                      renderWidget={renderWidget}
                    />
                  </div>
                )}
              </div>
            )}
          </DndContext>
          ) : (
            <div className="rounded-2xl border border-dashed border-border/40 bg-white/60 dark:bg-zinc-900/60 p-8 text-center">
              <p className="text-sm font-serif text-ink dark:text-dark-ink mb-2">{t('homeDashboard.layoutEmptyTitle')}</p>
              <p className="text-[11px] text-concrete mb-4 max-w-md mx-auto">{t('homeDashboard.layoutEmptyHint')}</p>
              <button
                type="button"
                onClick={handleReset}
                className="inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-brand-accent text-white text-[10px] font-mono uppercase font-bold hover:bg-brand-accent/90 transition-colors"
              >
                <RotateCcw size={12} />
                {t('homeDashboard.widgetReset')}
              </button>
            </div>
          )
        ) : (
          <div className="grid grid-cols-12 gap-5">
            <div className="col-span-12 h-20 rounded-2xl bg-stone-50 dark:bg-zinc-950/30 animate-pulse" />
            <div className="col-span-12 lg:col-span-8 h-48 rounded-2xl bg-stone-50 dark:bg-zinc-950/30 animate-pulse" />
            <div className="col-span-12 lg:col-span-4 h-48 rounded-2xl bg-stone-50 dark:bg-zinc-950/30 animate-pulse" />
          </div>
        )}
      </div>

      <div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-40 flex items-center gap-2 px-3 py-2 rounded-2xl bg-ink/92 dark:bg-zinc-900/95 text-white shadow-xl border border-white/10 backdrop-blur-md">
        {editMode ? (
          <>
            <button
              type="button"
              onClick={() => setCatalogOpen(v => !v)}
              className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase font-bold px-3 py-2 rounded-xl bg-white/10 hover:bg-white/15 transition-colors"
            >
              <Plus size={12} />
              {t('homeDashboard.widgetCatalog')}
              {hidden.length > 0 && (
                <span className="px-1.5 py-0.5 rounded-md bg-brand-accent/90 text-[9px]">{hidden.length}</span>
              )}
            </button>
            <button
              type="button"
              onClick={handleReset}
              className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase font-bold px-3 py-2 rounded-xl bg-white/10 hover:bg-white/15 transition-colors"
            >
              <RotateCcw size={12} />
              {t('homeDashboard.widgetReset')}
            </button>
            <button
              type="button"
              onClick={() => { setEditMode(false); setCatalogOpen(false) }}
              className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase font-bold px-3 py-2 rounded-xl bg-brand-accent text-white hover:bg-brand-accent/90 transition-colors"
            >
              <Check size={12} />
              {t('homeDashboard.widgetDone')}
            </button>
          </>
        ) : (
          <button
            type="button"
            onClick={() => setEditMode(true)}
            className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase font-bold px-4 py-2 rounded-xl bg-white/10 hover:bg-white/15 transition-colors"
          >
            <LayoutGrid size={12} />
            {t('homeDashboard.widgetCustomize')}
          </button>
        )}
      </div>

      {editMode && catalogOpen && (
        <div className="fixed bottom-20 left-1/2 -translate-x-1/2 z-40 w-[min(520px,calc(100vw-2rem))] max-h-[min(60vh,480px)] overflow-y-auto custom-scrollbar p-4 rounded-2xl bg-white dark:bg-zinc-900 border border-border/40 shadow-2xl">
          <p className="text-[9px] font-mono font-bold uppercase tracking-wider text-concrete mb-3">
            {t('homeDashboard.widgetCatalogTitle')}
          </p>
          <div className="space-y-4">
            {DASHBOARD_CATEGORY_ORDER.map(category => {
              const ids = catalog[category]
              if (ids.length === 0) return null
              return (
                <div key={category}>
                  <p className="text-[8px] font-mono font-bold uppercase tracking-[0.15em] text-brand-accent mb-2">
                    {t(`homeDashboard.widgetCategories.${category}`)}
                  </p>
                  <div className="space-y-1.5">
                    {ids.map(id => {
                      const meta = DASHBOARD_WIDGET_META[id]
                      const active = isWidgetVisible(layout, id)
                      return (
                        <button
                          key={id}
                          type="button"
                          onClick={() => !meta.required && handleToggle(id)}
                          disabled={meta.required}
                          className={`w-full flex items-start gap-3 p-2.5 rounded-xl border text-start transition-colors ${
                            active
                              ? 'border-brand-accent/30 bg-brand-accent/[0.04]'
                              : 'border-border/25 bg-stone-50/80 dark:bg-zinc-950/40 hover:border-brand-accent/25'
                          } ${meta.required ? 'opacity-80 cursor-default' : 'cursor-pointer'}`}
                        >
                          <div className={`mt-0.5 shrink-0 w-6 h-6 rounded-lg flex items-center justify-center ${
                            active ? 'bg-brand-accent/15 text-brand-accent' : 'bg-stone-200/60 dark:bg-zinc-800 text-concrete'
                          }`}>
                            {active ? <Eye size={11} /> : <EyeOff size={11} />}
                          </div>
                          <div className="min-w-0 flex-1">
                            <p className="text-[11px] font-mono font-bold uppercase tracking-wide text-ink dark:text-dark-ink">
                              {t(`homeDashboard.widgets.${id}`)}
                            </p>
                            <p className="text-[10px] text-concrete leading-snug mt-0.5">
                              {t(`homeDashboard.widgetDescriptions.${id}`)}
                            </p>
                          </div>
                          {!meta.required && (
                            <span className={`shrink-0 text-[9px] font-mono font-bold uppercase px-2 py-1 rounded-lg ${
                              active ? 'text-concrete' : 'text-brand-accent bg-brand-accent/10'
                            }`}>
                              {active ? t('homeDashboard.widgetActive') : t('homeDashboard.widgetAddShort')}
                            </span>
                          )}
                        </button>
                      )
                    })}
                  </div>
                </div>
              )
            })}
          </div>
        </div>
      )}
    </>
  )
}
