'use client';

import React, { useState, useEffect, useMemo } from 'react';
import { useRouter } from 'next/navigation';
import { DndContext, closestCenter, PointerSensor, KeyboardSensor, useSensor, useSensors, DragEndEvent } from '@dnd-kit/core';
import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable, arrayMove } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

interface NavItem {
  id: number;
  label: string;
  url: string;
  itemType: string;
  sourceId: string | null;
  menuLocation: string;
  parentId: number | null;
  parentCategory: string | null;
  sortOrder: number;
  isActive: boolean;
  openInNewTab: boolean;
}

interface Category {
  id: string;
  name: string;
  slug: string;
}

interface NavigationManagerModalProps {
  onClose: () => void;
}

const LOCATION_CONFIG: Record<string, { label: string; emoji: string; color: string }> = {
  top_header: { label: 'Top Header (Pages/Links)', emoji: '📌', color: '#1e40af' },
  category_bar: { label: 'Main Categories (Header)', emoji: '🏷️', color: '#059669' },
  footer: { label: 'Footer', emoji: '📄', color: '#374151' },
};
const LOCATION_ORDER = ['top_header', 'category_bar', 'footer'];

const PillToggle = ({ isActive, onChange, disabled = false }: { isActive: boolean, onChange: (val: boolean) => void, disabled?: boolean }) => (
  <svg 
    width="36" height="20" viewBox="0 0 36 20" 
    onClick={() => !disabled && onChange(!isActive)}
    style={{ cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1 }}
  >
    <rect x="0" y="0" width="36" height="20" rx="10" fill={isActive ? "#22c55e" : "#d1d5db"} style={{ transition: "fill 0.2s" }} />
    <circle cx={isActive ? "26" : "10"} cy="10" r="8" fill="#ffffff" style={{ transition: "cx 0.2s" }} />
  </svg>
);

function SortableWrapper({ id, children }: { id: string | number, children: (dndProps: any) => React.ReactNode }) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
  return (
    <div ref={setNodeRef} style={{ transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.4 : 1, zIndex: isDragging ? 10 : 1, position: isDragging ? 'relative' : 'static' }}>
      {children({ ...attributes, ...listeners })}
    </div>
  );
}

export function NavigationManagerModal({ onClose }: NavigationManagerModalProps) {
  const router = useRouter();
  const [initialItems, setInitialItems] = useState<NavItem[]>([]);
  const [items, setItems] = useState<NavItem[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);
  const [deletedIds, setDeletedIds] = useState<Set<number>>(new Set());
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [editingItemId, setEditingItemId] = useState<number | null>(null);

  const [editDraft, setEditDraft] = useState<{
    label: string;
    url: string;
    menuLocation: string;
    parentId: number | null;
    parentCategory: string | null;
  } | null>(null);

  const [pendingUrlChange, setPendingUrlChange] = useState<{ id: number, newUrl: string, applyFn: () => void } | null>(null);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  );

  useEffect(() => {
    const loadData = async () => {
      try {
        const [itemsRes, catsRes] = await Promise.all([
          fetch('/api/navigation-items?all=1'),
          fetch('/api/editor/categories')
        ]);
        const itemsJson = await itemsRes.json();
        const catsJson = await catsRes.json();

        let loadedItems = itemsJson.items || [];
        const loadedCats = catsJson.categories || [];
        
        // Inject ghost rows for categories missing from DB
        const existingCatSlugs = new Set(loadedItems.filter((i: any) => i.itemType === 'category').map((i: any) => i.url.replace('/category/', '')));
        const missingCats = loadedCats.filter((c: any) => !existingCatSlugs.has(c.slug));
        
        if (missingCats.length > 0) {
          const newGhostRows = missingCats.map((cat: any, idx: number) => ({
            id: -1000 - idx, // temporary negative ID
            label: cat.name,
            url: `/category/${cat.slug}`,
            itemType: 'category',
            sourceId: cat.slug,
            menuLocation: 'category_bar',
            parentId: null,
            parentCategory: null,
            sortOrder: loadedItems.length + idx + 1,
            isActive: true,
            openInNewTab: false,
          }));
          loadedItems = [...loadedItems, ...newGhostRows];
        }

        setItems(loadedItems);
        setInitialItems(loadedItems);
        setCategories(loadedCats);
      } catch (err) {
        console.error('Failed to load navigation data:', err);
      } finally {
        setLoading(false);
      }
    };
    loadData();
  }, []);

  const hasChanges = useMemo(() => {
    if (deletedIds.size > 0) return true;
    if (items.length !== initialItems.length) return true;
    for (const item of items) {
      const init = initialItems.find(i => i.id === item.id);
      if (!init) return true;
      if (
        item.label !== init.label ||
        item.url !== init.url ||
        item.menuLocation !== init.menuLocation ||
        item.sortOrder !== init.sortOrder ||
        item.isActive !== init.isActive ||
        item.parentId !== init.parentId ||
        item.parentCategory !== init.parentCategory
      ) return true;
    }
    return false;
  }, [items, initialItems, deletedIds]);

  const handleClose = () => {
    if (hasChanges) {
      if (confirm('You have unsaved changes. Are you sure you want to discard them?')) {
        onClose();
      }
    } else {
      onClose();
    }
  };

  const handleSaveAll = async () => {
    setSaving(true);
    try {
      const res = await fetch('/api/navigation-items/bulk-save', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          items,
          deletedIds: Array.from(deletedIds),
        }),
      });
      if (!res.ok) throw new Error('Save failed');
      
      router.refresh();
      onClose();
    } catch (err) {
      console.error(err);
      alert('Failed to save navigation changes');
    } finally {
      setSaving(false);
    }
  };

  const toggleVisibility = (id: number, val: boolean) => {
    setItems(prev => prev.map(item => item.id === id ? { ...item, isActive: val } : item));
  };

  const moveItem = (id: number | string, direction: 'up' | 'down') => {
    const isCat = typeof id === 'string' && id.startsWith('cat_');
    const actualId = isCat ? id.replace('cat_', '') : id;

    let targetIdx = -1;
    let siblings: any[] = [];
    
    if (isCat) {
      // It's a category. We can't move categories easily since they are locked, 
      // but if we support reordering categories among top_header items...
      // Actually, categories are usually fixed at the top, or we can allow them to move among root items.
      const cat = categories.find(c => c.slug === actualId);
      if (!cat) return;
      siblings = [
        ...categories.map(c => ({ id: `cat_${c.slug}`, type: 'cat', sortOrder: 0, raw: c })),
        ...items.filter(i => i.menuLocation === 'top_header' && !i.parentId && !i.parentCategory).map(i => ({ id: i.id, type: 'item', sortOrder: i.sortOrder, raw: i }))
      ];
    }
    
    if (!isCat) {
      const itemIdx = items.findIndex(i => i.id === actualId);
      if (itemIdx === -1) return;
      const item = items[itemIdx];

      siblings = items
        .filter(i => i.menuLocation === item.menuLocation && i.parentId === item.parentId && i.parentCategory === item.parentCategory)
        .sort((a, b) => a.sortOrder - b.sortOrder);

      const currentPos = siblings.findIndex(i => i.id === actualId);
      if (direction === 'up' && currentPos > 0) {
        const swapWith = siblings[currentPos - 1];
        setItems(prev => prev.map(i => {
          if (i.id === item.id) return { ...i, sortOrder: swapWith.sortOrder };
          if (i.id === swapWith.id) return { ...i, sortOrder: item.sortOrder };
          return i;
        }));
      } else if (direction === 'down' && currentPos < siblings.length - 1) {
        const swapWith = siblings[currentPos + 1];
        setItems(prev => prev.map(i => {
          if (i.id === item.id) return { ...i, sortOrder: swapWith.sortOrder };
          if (i.id === swapWith.id) return { ...i, sortOrder: item.sortOrder };
          return i;
        }));
      }
    }
  };

  const handleDragEndLocal = (event: DragEndEvent, locKey: string, currentRoots: any[]) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;

    const oldIdx = currentRoots.findIndex(i => i.id === active.id);
    const newIdx = currentRoots.findIndex(i => i.id === over.id);
    const newOrder = arrayMove(currentRoots, oldIdx, newIdx);

    setItems(prev => {
      const others = prev.filter(i => !(i.menuLocation === locKey && i.parentId === null && i.parentCategory === null));
      const newlyOrdered = newOrder.map((item, idx) => {
        // If it's a category from items array, update its sortOrder
        const found = prev.find(i => i.id === item.id);
        if (found) return { ...found, sortOrder: idx + 1 };
        return item; // Fallback
      });
      return [...others, ...newlyOrdered];
    });
  };

  const startEditing = (item: NavItem) => {
    setEditingItemId(item.id);
    setEditDraft({
      label: item.label,
      url: item.url,
      menuLocation: item.menuLocation,
      parentId: item.parentId,
      parentCategory: item.parentCategory,
    });
  };

  const cancelEditing = () => {
    setEditingItemId(null);
    setEditDraft(null);
  };

  const saveEditing = (originalItem: NavItem) => {
    if (!editDraft) return;
    if (originalItem.url !== editDraft.url && originalItem.id > 0 && originalItem.itemType !== 'category') {
      setPendingUrlChange({
        id: originalItem.id,
        newUrl: editDraft.url,
        applyFn: () => {
          applyEdit(originalItem.id, editDraft);
          setPendingUrlChange(null);
        }
      });
      return;
    }
    applyEdit(originalItem.id, editDraft);
  };

  const applyEdit = (id: number, draft: any) => {
    setItems(prev => prev.map(item => item.id === id ? { ...item, ...draft } : item));
    setEditingItemId(null);
    setEditDraft(null);
  };

  const getBadge = (type: string) => {
    switch(type) {
      case 'category': return <span className="bg-blue-100 text-blue-800 text-[10px] px-1.5 py-0.5 rounded font-bold uppercase">CAT</span>;
      case 'custom_page': return <span className="bg-amber-100 text-amber-800 text-[10px] px-1.5 py-0.5 rounded font-bold uppercase">PAGE</span>;
      case 'external': return <span className="bg-gray-100 text-gray-800 text-[10px] px-1.5 py-0.5 rounded font-bold uppercase">LINK</span>;
      case 'dropdown': return <span className="bg-purple-100 text-purple-800 text-[10px] px-1.5 py-0.5 rounded font-bold uppercase">DROP</span>;
      default: return <span className="bg-gray-100 text-gray-800 text-[10px] px-1.5 py-0.5 rounded font-bold uppercase">{type}</span>;
    }
  };

  const renderItemRow = (item: NavItem, depth = 0, dndProps?: any) => {
    const isEditing = editingItemId === item.id;
    const isLockedCategory = item.itemType === 'category';

    const childItems = items
      .filter(i => {
        // Match by parentId (string or number)
        if (i.parentId && i.parentId.toString() === item.id.toString()) return true;
        
        // Match by parentCategory (if parent is a category)
        if (isLockedCategory && i.parentCategory === item.url.replace('/category/', '')) return true;
        
        return false;
      })
      .sort((a, b) => a.sortOrder - b.sortOrder);

    return (
      <React.Fragment key={`item-${item.id}`}>
        <div className={`flex items-center gap-3 py-2 px-2 hover:bg-gray-50 border-b border-gray-100 rounded bg-white ${depth > 0 ? 'ml-6' : ''}`}>
          <div className="w-6 flex items-center justify-center text-gray-400">
            {depth === 0 ? (
              <div {...dndProps} className="cursor-grab hover:text-gray-700 p-1" title="Drag to reorder">
                ⠿
              </div>
            ) : '⣿'}
          </div>
          <PillToggle isActive={item.isActive} onChange={(val) => toggleVisibility(item.id, val)} />
          
          <div className="flex-1 min-w-0">
            {isEditing ? (
              <div className="flex flex-col gap-2 py-1">
                <input 
                  type="text" 
                  value={editDraft?.label || ''} 
                  onChange={e => setEditDraft(prev => ({ ...prev!, label: e.target.value }))}
                  disabled={item.itemType === 'custom_page' || isLockedCategory}
                  className="border rounded px-2 py-1 text-sm disabled:bg-gray-100"
                  placeholder="Label"
                />
                <input 
                  type="text" 
                  value={editDraft?.url || ''} 
                  onChange={e => setEditDraft(prev => ({ ...prev!, url: e.target.value }))}
                  disabled={item.itemType === 'custom_page' || isLockedCategory}
                  className="border rounded px-2 py-1 text-sm text-gray-500 disabled:bg-gray-100"
                  placeholder="URL"
                />
                <select 
                  className="border rounded px-2 py-1 text-sm bg-blue-50 border-blue-200"
                  value={editDraft?.menuLocation || item.menuLocation}
                  onChange={e => setEditDraft(prev => ({ ...prev!, menuLocation: e.target.value }))}
                >
                  {Object.entries(LOCATION_CONFIG).map(([key, config]) => (
                    <option key={key} value={key}>{config.label}</option>
                  ))}
                </select>
                <select 
                  className="border rounded px-2 py-1 text-sm"
                  value={editDraft?.parentCategory ? `cat_${editDraft.parentCategory}` : (editDraft?.parentId ? `parent_${editDraft.parentId}` : '')}
                  onChange={e => {
                    const val = e.target.value;
                    if (!val) {
                      setEditDraft(prev => ({ ...prev!, parentId: null, parentCategory: null }));
                    } else if (val.startsWith('cat_')) {
                      setEditDraft(prev => ({ ...prev!, parentCategory: val.replace('cat_', ''), parentId: null }));
                    } else if (val.startsWith('parent_')) {
                      setEditDraft(prev => ({ ...prev!, parentId: parseInt(val.replace('parent_', ''), 10), parentCategory: null }));
                    }
                  }}
                  disabled={isLockedCategory}
                >
                  <option value="">-- No Parent --</option>
                  <optgroup label="🔒 Ranktraction Categories">
                    {categories.map(c => (
                      <option key={`opt-cat-${c.id}`} value={`cat_${c.slug}`}>{c.name}</option>
                    ))}
                  </optgroup>
                  <optgroup label="Custom Pages / Links">
                    {items.filter(i => i.menuLocation === item.menuLocation && i.id !== item.id && !i.parentId && !i.parentCategory && i.itemType !== 'category').map(i => (
                      <option key={`opt-parent-${i.id}`} value={`parent_${i.id}`}>{i.label}</option>
                    ))}
                  </optgroup>
                </select>
                <div className="flex gap-2">
                  <button onClick={() => saveEditing(item)} className="bg-blue-600 text-white px-3 py-1 rounded text-sm hover:bg-blue-700">Done</button>
                  <button onClick={cancelEditing} className="bg-gray-200 text-gray-800 px-3 py-1 rounded text-sm hover:bg-gray-300">Cancel</button>
                </div>
              </div>
            ) : (
              <>
                <div className="flex items-center gap-2">
                  <span className="font-semibold text-gray-900 text-sm truncate">{item.label}</span>
                  {getBadge(item.itemType)}
                </div>
                <div className="text-xs text-gray-500 truncate">{item.url}</div>
              </>
            )}
          </div>
          
          {!isEditing && (
            <div className="flex items-center gap-1">
              <button onClick={() => moveItem(item.id, 'up')} className="p-1 text-gray-400 hover:text-gray-700 hover:bg-gray-100 rounded" title="Move Up">▲</button>
              <button onClick={() => moveItem(item.id, 'down')} className="p-1 text-gray-400 hover:text-gray-700 hover:bg-gray-100 rounded" title="Move Down">▼</button>
              {isLockedCategory ? (
                <span className="p-1 text-gray-400 ml-1" title="This category is synced from Ranktraction. It cannot be edited or deleted from the Navigation Manager.">🔒</span>
              ) : (
                <button onClick={() => startEditing(item)} className="p-1 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded ml-1" title="Edit Item">✏️</button>
              )}
            </div>
          )}
        </div>
        {childItems.map(child => renderItemRow(child, depth + 1))}
      </React.Fragment>
    );
  };

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[99999] p-4">
      <div className="bg-white rounded-xl shadow-2xl w-full max-w-2xl max-h-[90vh] flex flex-col overflow-hidden">
        
        <div className="flex items-center justify-between p-4 border-b border-gray-200 bg-gray-50">
          <div className="flex items-center gap-3">
            <h2 className="text-xl font-bold text-gray-800 flex items-center gap-2">
              🧭 Navigation Manager
            </h2>
            {hasChanges && (
              <span className="bg-amber-100 text-amber-800 text-xs px-2 py-1 rounded-full font-medium flex items-center gap-1">
                ⚠️ You have unsaved changes
              </span>
            )}
          </div>
          <button onClick={handleClose} className="text-gray-400 hover:text-gray-600 transition-colors text-2xl leading-none">
            &times;
          </button>
        </div>

        <div className="flex-1 overflow-y-auto p-6 bg-white space-y-8">
          {loading ? (
            <div className="flex justify-center py-10">
              <svg className="animate-spin h-8 w-8 text-blue-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
              </svg>
            </div>
          ) : (
            LOCATION_ORDER.map(locKey => {
              const locConfig = LOCATION_CONFIG[locKey];
              if (!locConfig) return null;
              
              const isTopHeader = locKey === 'top_header';
              let topLevelItems = items
                .filter(i => i.menuLocation === locKey && !i.parentId && !i.parentCategory)
                .sort((a, b) => a.sortOrder - b.sortOrder);

              return (
                <div key={locKey} className="border border-gray-200 rounded-lg overflow-hidden shadow-sm">
                  <div className="bg-gray-100 px-4 py-3 flex items-center justify-between border-b border-gray-200">
                    <div className="flex items-center gap-2 font-bold text-gray-800">
                      <span>{locConfig.emoji}</span>
                      {locConfig.label}
                    </div>
                    <div className="text-sm text-gray-500 font-medium">
                      [{topLevelItems.length} top-level items]
                    </div>
                  </div>
                  <div className="p-2">
                    <DndContext
                      sensors={sensors}
                      collisionDetection={closestCenter}
                      onDragEnd={event => handleDragEndLocal(event, locKey, topLevelItems)}
                    >
                      <SortableContext items={topLevelItems.map(i => i.id)} strategy={verticalListSortingStrategy}>
                        {topLevelItems.map(item => (
                          <SortableWrapper key={item.id} id={item.id}>
                            {(dndProps) => renderItemRow(item, 0, dndProps)}
                          </SortableWrapper>
                        ))}
                      </SortableContext>
                    </DndContext>
                    
                    {topLevelItems.length === 0 && (
                      <div className="text-gray-400 text-sm text-center py-6 italic">
                        No items in this location yet.
                      </div>
                    )}
                  </div>
                </div>
              );
            })
          )}
        </div>

        <div className="p-4 border-t border-gray-200 bg-gray-50 flex justify-end gap-3">
          <button 
            onClick={handleClose}
            className="px-4 py-2 text-gray-600 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 font-medium transition-colors"
          >
            Cancel
          </button>
          <button 
            onClick={handleSaveAll}
            disabled={saving || loading || !hasChanges}
            className="px-5 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
          >
            {saving ? 'Saving...' : '💾 Save Changes'}
          </button>
        </div>
      </div>

      {pendingUrlChange && (
        <div className="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center z-[100000] p-4">
          <div className="bg-white rounded-lg shadow-2xl w-full max-w-md overflow-hidden">
            <div className="bg-amber-50 border-b border-amber-200 p-4 flex items-start gap-3">
              <span className="text-2xl">⚠️</span>
              <div>
                <h3 className="font-bold text-amber-900 text-lg">SEO URL Change Warning</h3>
                <p className="text-amber-800 text-sm mt-1 leading-relaxed">
                  If you change the URL of this page and it is already ranking on Google, the ranking may be negatively affected. Are you sure you want to proceed?
                </p>
              </div>
            </div>
            <div className="p-4 bg-gray-50 flex justify-end gap-3 border-t border-gray-200">
              <button 
                onClick={() => setPendingUrlChange(null)}
                className="px-4 py-2 text-gray-600 bg-white border border-gray-300 rounded hover:bg-gray-50 text-sm font-medium transition-colors"
              >
                Cancel
              </button>
              <button 
                onClick={() => pendingUrlChange.applyFn()}
                className="px-4 py-2 bg-amber-600 text-white rounded hover:bg-amber-700 text-sm font-medium transition-colors"
              >
                Yes, Change URL
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
