import React, { useRef, useState } from "react";
import { cn } from "@/lib/utils";
import { ScenarioItem } from "./scenario-item";
import { AddScenarioButton } from "./borrowing-capacity-atoms";

/**
 * Left-sidebar organism for the Borrowing Capacity page.
 *
 * Renders a titled list of selectable, editable `ScenarioItem` rows followed
 * by an `AddScenarioButton`. Drag-and-drop reordering is handled internally
 * via the HTML5 DnD API; the consumer receives the final order via `onReorder`.
 */

export interface ScenarioListScenario {
  /** Unique identifier */
  id: string;
  /** Display name (e.g. "Default Scenario") */
  name: string;
  /** Secondary descriptor (e.g. "Owner Occupier") */
  description?: string;
}

export interface ScenarioListProps {
  /** Section heading (default: "New Loans") */
  title?: string;
  /** Ordered list of scenarios to render */
  scenarios: ScenarioListScenario[];
  /** ID of the currently active scenario */
  selectedId?: string;
  /** Called when a scenario row is clicked */
  onSelect?: (id: string) => void;
  /** Called when "Update Scenario" is clicked in a kebab menu */
  onEdit?: (id: string) => void;
  /** Called when "Delete Scenario" is clicked in a kebab menu */
  onDelete?: (id: string) => void;
  /** Called when the Add button is clicked */
  onAdd?: () => void;
  /** Label for the add button (default: "Add New Scenario") */
  addLabel?: string;
  /**
   * Maximum number of scenarios allowed. When `scenarios.length >= maxScenarios`
   * the add button is disabled.
   */
  maxScenarios?: number;
  /** All items show a drag handle when true (default: true) */
  isDraggable?: boolean;
  /**
   * Called with the new ordered ID array after a drag-and-drop reorder.
   * The consumer is responsible for updating the `scenarios` prop accordingly.
   */
  onReorder?: (orderedIds: string[]) => void;
  className?: string;
}

export function ScenarioList({
  title = "New Loans",
  scenarios,
  selectedId,
  onSelect,
  onEdit,
  onDelete,
  onAdd,
  addLabel = "Add New Scenario",
  maxScenarios,
  isDraggable = true,
  onReorder,
  className,
}: ScenarioListProps) {
  const isAddDisabled =
    maxScenarios !== undefined && scenarios.length >= maxScenarios;

  // ── Drag & drop state ───────────────────────────────────────────────────────
  const draggingId = useRef<string | null>(null);
  const [dragOverId, setDragOverId] = useState<string | null>(null);

  const handleDragStart = (id: string) => (e: React.DragEvent) => {
    draggingId.current = id;
    e.dataTransfer.effectAllowed = "move";
  };

  const handleDragOver = (id: string) => (e: React.DragEvent) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
    if (id !== draggingId.current) setDragOverId(id);
  };

  const handleDragLeave = () => setDragOverId(null);

  const handleDrop = (targetId: string) => (e: React.DragEvent) => {
    e.preventDefault();
    setDragOverId(null);

    const sourceId = draggingId.current;
    draggingId.current = null;

    if (!sourceId || sourceId === targetId || !onReorder) return;

    const ids = scenarios.map((s) => s.id);
    const fromIdx = ids.indexOf(sourceId);
    const toIdx = ids.indexOf(targetId);
    if (fromIdx === -1 || toIdx === -1) return;

    const reordered = [...ids];
    reordered.splice(fromIdx, 1);
    reordered.splice(toIdx, 0, sourceId);
    onReorder(reordered);
  };

  const handleDragEnd = () => {
    draggingId.current = null;
    setDragOverId(null);
  };

  return (
    <div className={cn("flex flex-col", className)}>
      <div className="border-b border-border px-4 py-3">
        <p className="text-sm font-semibold uppercase tracking-widest text-muted-foreground">
          {title}
        </p>
      </div>

      {scenarios.map((scenario) => (
        <ScenarioItem
          key={scenario.id}
          name={scenario.name}
          description={scenario.description}
          isSelected={scenario.id === selectedId}
          isDraggable={isDraggable}
          isDragOver={scenario.id === dragOverId}
          onSelect={() => onSelect?.(scenario.id)}
          onEdit={onEdit ? () => onEdit(scenario.id) : undefined}
          onDelete={onDelete ? () => onDelete(scenario.id) : undefined}
          onDragStart={isDraggable ? handleDragStart(scenario.id) : undefined}
          onDragOver={isDraggable ? handleDragOver(scenario.id) : undefined}
          onDragLeave={isDraggable ? handleDragLeave : undefined}
          onDrop={isDraggable ? handleDrop(scenario.id) : undefined}
          onDragEnd={isDraggable ? handleDragEnd : undefined}
        />
      ))}

      <div className="p-3">
        <AddScenarioButton
          title={addLabel}
          disabled={isAddDisabled}
          onClick={onAdd}
        />
      </div>
    </div>
  );
}
