import { useCallback } from "react";
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, type DragEndEvent } from "@dnd-kit/core";
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import {
  EyeOpenIcon,
  EyeNoneIcon,
  LockClosedIcon,
  LockOpen1Icon,
  DragHandleDots2Icon,
  TrashIcon,
  ContainerIcon,
  GearIcon,
  ChevronDownIcon,
  ChevronRightIcon,
} from "@radix-ui/react-icons";
import * as Tooltip from "@radix-ui/react-tooltip";
import { useCanvasStore, useContainerSelected } from "@/stores/canvasStore";
import { useLayoutPersistStore } from "@/stores/layoutPersistStore";
import type { CanvasElement, ElementType } from "@/types";
import { ElementIcon } from "@/components/icons/ElementIcons";

// Element type colors for visual distinction
const elementColors: Record<ElementType, string> = {
  regularPrice: "#64748b",
  salePrice: "#64748b",
  discountBadge: "#64748b",
  currencySymbol: "#64748b",
  text: "#64748b",
  variablePriceRange: "#64748b",
};

interface LayerItemProps {
  element: CanvasElement;
  isSelected: boolean;
  onSelect: (id: string) => void;
  onToggleVisibility: (id: string) => void;
  onToggleLock: (id: string) => void;
  onDelete: (id: string) => void;
}

function LayerItem({ element, isSelected, onSelect, onToggleVisibility, onToggleLock, onDelete }: LayerItemProps) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: element.id });

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

  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onSelect(element.id);
    },
    [element.id, onSelect]
  );

  const handleVisibilityClick = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onToggleVisibility(element.id);
    },
    [element.id, onToggleVisibility]
  );

  const handleLockClick = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onToggleLock(element.id);
    },
    [element.id, onToggleLock]
  );

  const handleDeleteClick = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onDelete(element.id);
    },
    [element.id, onDelete]
  );

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`
        group flex items-center gap-2 px-2 py-1.5 rounded-md cursor-pointer
        transition-colors duration-150
        ${isSelected ? "bg-primary/10 ring-1 ring-primary/30" : "hover:bg-surface-secondary"}
        ${!element.visible ? "opacity-50" : ""}
      `}
      onClick={handleClick}
    >
      {/* Drag handle */}
      <button
        {...attributes}
        {...listeners}
        className="p-0.5 text-text-muted hover:text-text cursor-grab active:cursor-grabbing"
        onClick={(e) => e.stopPropagation()}
      >
        <DragHandleDots2Icon className="w-4 h-4" />
      </button>

      {/* Element icon with color indicator */}
      <div className="flex items-center justify-center w-5 h-5 rounded">
        <ElementIcon type={element.type} className="w-5 h-5" />
      </div>

      {/* Element name */}
      <span className={`flex-1 text-sm truncate ${element.locked ? "text-text-muted" : "text-text"}`}>{element.name}</span>

      {/* Action buttons */}
      <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
        {/* Visibility toggle */}
        <Tooltip.Root>
          <Tooltip.Trigger asChild>
            <button
              onClick={handleVisibilityClick}
              className={`p-1 rounded hover:bg-surface-secondary ${element.visible ? "text-text-muted" : "text-warning"}`}
            >
              {element.visible ? <EyeOpenIcon className="w-3.5 h-3.5" /> : <EyeNoneIcon className="w-3.5 h-3.5" />}
            </button>
          </Tooltip.Trigger>
          <Tooltip.Portal>
            <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg" sideOffset={5}>
              {element.visible ? "Hide" : "Show"}
              <Tooltip.Arrow className="fill-text" />
            </Tooltip.Content>
          </Tooltip.Portal>
        </Tooltip.Root>

        {/* Lock toggle */}
        <Tooltip.Root>
          <Tooltip.Trigger asChild>
            <button
              onClick={handleLockClick}
              className={`p-1 rounded hover:bg-surface-secondary ${element.locked ? "text-warning" : "text-text-muted"}`}
            >
              {element.locked ? <LockClosedIcon className="w-3.5 h-3.5" /> : <LockOpen1Icon className="w-3.5 h-3.5" />}
            </button>
          </Tooltip.Trigger>
          <Tooltip.Portal>
            <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg" sideOffset={5}>
              {element.locked ? "Unlock" : "Lock"}
              <Tooltip.Arrow className="fill-text" />
            </Tooltip.Content>
          </Tooltip.Portal>
        </Tooltip.Root>

        {/* Delete button */}
        <Tooltip.Root>
          <Tooltip.Trigger asChild>
            <button onClick={handleDeleteClick} className="p-1 rounded hover:bg-danger/10 text-text-muted hover:text-error">
              <TrashIcon className="w-3.5 h-3.5" />
            </button>
          </Tooltip.Trigger>
          <Tooltip.Portal>
            <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg" sideOffset={5}>
              Delete
              <Tooltip.Arrow className="fill-text" />
            </Tooltip.Content>
          </Tooltip.Portal>
        </Tooltip.Root>
      </div>
    </div>
  );
}

/**
 * Container Item Component
 *
 * Fixed item at the top of the layer tree representing the oppb-price-container.
 * Cannot be removed, reordered, or hidden. Clicking opens container settings.
 */
interface ContainerItemProps {
  isSelected: boolean;
  onSelect: () => void;
}

function ContainerItem({ isSelected, onSelect }: ContainerItemProps) {
  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onSelect();
    },
    [onSelect]
  );

  return (
    <div
      className={`
        group flex items-center gap-2 px-2 py-1.5 rounded-md cursor-pointer
        transition-colors duration-150 border-b border-border mb-2
        ${isSelected ? "bg-primary/10 ring-1 ring-primary/30" : "hover:bg-surface-secondary"}
      `}
      onClick={handleClick}
      data-onboarding="container-settings"
    >
      {/* Fixed icon (no drag handle) */}
      <div className="p-0.5 text-text-muted/50">
        <ContainerIcon className="w-4 h-4" />
      </div>

      {/* Container icon with color indicator */}
      <div className="flex items-center justify-center w-5 h-5 rounded" style={{ backgroundColor: "rgba(37, 99, 235, 0.2)" }}>
        <span style={{ color: "#2563eb" }}>
          <ContainerIcon className="w-4 h-4" />
        </span>
      </div>

      {/* Container name */}
      <span className="flex-1 text-sm truncate text-text font-medium">Container</span>

      {/* Settings indicator */}
      <div className="flex items-center gap-0.5">
        <Tooltip.Root>
          <Tooltip.Trigger asChild>
            <button onClick={handleClick} className="p-1 rounded hover:bg-surface-secondary text-text-muted hover:text-primary">
              <GearIcon className="w-3.5 h-3.5" />
            </button>
          </Tooltip.Trigger>
          <Tooltip.Portal>
            <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg" sideOffset={5}>
              Container Settings
              <Tooltip.Arrow className="fill-text" />
            </Tooltip.Content>
          </Tooltip.Portal>
        </Tooltip.Root>
      </div>
    </div>
  );
}

export function LayerTree() {
  const elements = useCanvasStore((state) => state.elements);
  const selectedIds = useCanvasStore((state) => state.selectedIds);
  const containerSelected = useContainerSelected();
  const selectElement = useCanvasStore((state) => state.selectElement);
  const selectContainer = useCanvasStore((state) => state.selectContainer);
  const updateElement = useCanvasStore((state) => state.updateElement);
  const removeElement = useCanvasStore((state) => state.removeElement);
  const reorderElements = useCanvasStore((state) => state.reorderElements);

  // Persist collapsed state
  const isCollapsed = useLayoutPersistStore((state) => state.sidebarCollapsed.layers);
  const toggleSection = useLayoutPersistStore((state) => state.toggleSidebarSection);

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

  const handleDragEnd = useCallback(
    (event: DragEndEvent) => {
      const { active, over } = event;

      if (over && active.id !== over.id) {
        const oldIndex = elements.findIndex((el) => el.id === active.id);
        const newIndex = elements.findIndex((el) => el.id === over.id);
        reorderElements(oldIndex, newIndex);
      }
    },
    [elements, reorderElements]
  );

  const handleSelect = useCallback(
    (id: string) => {
      selectElement(id);
    },
    [selectElement]
  );

  const handleToggleVisibility = useCallback(
    (id: string) => {
      const element = elements.find((el) => el.id === id);
      if (element) {
        updateElement(id, { visible: !element.visible });
      }
    },
    [elements, updateElement]
  );

  const handleToggleLock = useCallback(
    (id: string) => {
      const element = elements.find((el) => el.id === id);
      if (element) {
        updateElement(id, { locked: !element.locked });
      }
    },
    [elements, updateElement]
  );

  const handleDelete = useCallback(
    (id: string) => {
      removeElement(id);
    },
    [removeElement]
  );

  // Sort elements by zIndex for display (highest first = on top)
  const sortedElements = [...elements].sort((a, b) => b.zIndex - a.zIndex);

  return (
    <Tooltip.Provider delayDuration={300}>
      <div className="flex flex-col flex-1 bg-surface border-l border-border">
        {/* Header */}
        <div className="flex items-center justify-between px-3 py-3 border-b border-border">
          <h3 className="text-sm font-semibold text-text">Layers</h3>
          <button
            onClick={() => toggleSection("layers")}
            className="p-1 text-text-muted hover:text-text rounded hover:bg-surface-secondary"
          >
            {isCollapsed ? <ChevronRightIcon className="w-4 h-4" /> : <ChevronDownIcon className="w-4 h-4" />}
          </button>
        </div>

        {/* Layer list */}
        {!isCollapsed && (
          <div className="flex-1 overflow-y-auto p-2">
            {/* Container Item - Always shown at top */}
            <ContainerItem isSelected={containerSelected} onSelect={selectContainer} />

            {elements.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-6 text-text-muted">
                <p className="text-sm">No layers yet</p>
                <p className="text-xs">Add elements from the toolbar</p>
              </div>
            ) : (
              <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
                <SortableContext items={sortedElements.map((el) => el.id)} strategy={verticalListSortingStrategy}>
                  <div className="flex flex-col gap-1">
                    {sortedElements.map((element) => (
                      <LayerItem
                        key={element.id}
                        element={element}
                        isSelected={selectedIds.includes(element.id)}
                        onSelect={handleSelect}
                        onToggleVisibility={handleToggleVisibility}
                        onToggleLock={handleToggleLock}
                        onDelete={handleDelete}
                      />
                    ))}
                  </div>
                </SortableContext>
              </DndContext>
            )}
          </div>
        )}

        {/* Footer with count */}
        {!isCollapsed && elements.length > 0 && (
          <div className="px-3 py-2 border-t border-border">
            <p className="text-xs text-text-muted">
              {elements.length} layer{elements.length !== 1 ? "s" : ""}
              {selectedIds.length > 0 && ` • ${selectedIds.length} selected`}
            </p>
          </div>
        )}
      </div>
    </Tooltip.Provider>
  );
}
