import { useState } from "react";
import { Plus, ChevronRight } from "lucide-react";
import { motion, useReducedMotion } from "framer-motion";
import { fadeSlideUp, springs, staggerContainer } from "@/lib/motion";
import { useDroppable } from "@dnd-kit/core";
import {
  SortableContext,
  verticalListSortingStrategy,
  useSortable,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
import { Button } from "@/components/ui/button";
import { ColumnHeader } from "@/components/board/ColumnHeader";
import { AddCardInput } from "@/components/board/AddCardInput";
import { CardThumbnail } from "@/components/board/CardThumbnail";
import { useBoardStore } from "@/stores/board-store";
import type { Column } from "@/types/board";

const WIDTH_MAP = {
  narrow: 180,
  standard: 280,
  wide: 360,
} as const;

interface KanbanColumnProps {
  column: Column;
  filteredCardIds?: string[];
  focusedCardId?: string | null;
  onCardClick?: (cardId: string) => void;
  isNew?: boolean;
}

export function KanbanColumn({ column, filteredCardIds, focusedCardId, onCardClick, isNew }: KanbanColumnProps) {
  const [showAddCard, setShowAddCard] = useState(false);
  const board = useBoardStore((s) => s.board);
  const toggleColumnCollapse = useBoardStore((s) => s.toggleColumnCollapse);
  const prefersReducedMotion = useReducedMotion();

  const width = WIDTH_MAP[column.width];

  // Make the column itself sortable (for column reordering)
  const {
    attributes,
    listeners,
    setNodeRef: setSortableNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({
    id: column.id,
    data: { type: "column" },
  });

  // Make the column a droppable target so empty columns can receive cards
  const { setNodeRef: setDroppableNodeRef } = useDroppable({
    id: `column-droppable-${column.id}`,
    data: { type: "column", columnId: column.id },
  });

  const borderTop = column.color
    ? `3px solid oklch(55% 0.12 ${column.color})`
    : board?.color
      ? `3px solid ${board.color}30`
      : undefined;

  const displayCardIds = filteredCardIds ?? column.cardIds;
  const isFiltering = filteredCardIds != null;
  const cardCount = column.cardIds.length;

  const wipTint = column.wipLimit != null
    ? cardCount > column.wipLimit
      ? "oklch(70% 0.08 25 / 15%)"
      : cardCount === column.wipLimit
        ? "oklch(75% 0.08 70 / 15%)"
        : undefined
    : undefined;

  return (
    <motion.div
      ref={setSortableNodeRef}
      style={{
        transform: CSS.Transform.toString(transform),
        transition,
        opacity: isDragging ? 0.5 : undefined,
      }}
      animate={{ width: column.collapsed ? 40 : width, opacity: 1 }}
      initial={isNew ? { width: 0, opacity: 0 } : false}
      exit={{ width: 0, opacity: 0 }}
      transition={springs.bouncy}
      className="shrink-0 overflow-hidden"
      {...attributes}
    >
    {column.collapsed ? (
      <button
        onClick={() => toggleColumnCollapse(column.id)}
        className="flex h-full w-full flex-col items-center gap-2 rounded-lg bg-pylon-column py-3 hover:bg-pylon-column/80 transition-colors"
        style={{ borderTop }}
        {...listeners}
      >
        <ChevronRight className="size-3.5 text-pylon-text-secondary" />
        <span
          className="font-mono text-xs font-semibold uppercase tracking-widest text-pylon-text-secondary"
          style={{ writingMode: "vertical-rl", transform: "rotate(180deg)" }}
        >
          {column.title}
        </span>
        <span className="mt-auto font-mono text-xs text-pylon-text-secondary">
          {cardCount}
        </span>
      </button>
    ) : (
    <motion.section
      className="group/column flex h-full flex-col overflow-hidden rounded-lg bg-pylon-column"
      aria-label={`${column.title} column, ${cardCount} card${cardCount !== 1 ? "s" : ""}`}
      style={{ borderTop, backgroundColor: wipTint }}
      variants={fadeSlideUp}
      initial={isNew || prefersReducedMotion ? false : undefined}
      animate={isNew ? "visible" : undefined}
      transition={springs.bouncy}
    >
      {/* The column header is the drag handle for column reordering */}
      <div {...listeners}>
        <ColumnHeader column={column} cardCount={cardCount} filteredCount={isFiltering ? displayCardIds.length : undefined} />
      </div>

      {/* Card list - wrapped in SortableContext for within-column sorting */}
      <SortableContext
        items={column.cardIds}
        strategy={verticalListSortingStrategy}
      >
        <OverlayScrollbarsComponent
          className="flex-1"
          options={{ scrollbars: { theme: "os-theme-pylon", autoHide: "scroll", autoHideDelay: 600, clickScroll: true }, overflow: { x: "hidden" } }}
          defer
        >
          <motion.ul
            ref={setDroppableNodeRef}
            className="flex min-h-[40px] list-none flex-col"
            style={{ gap: `calc(0.5rem * var(--density-factor))`, padding: `calc(0.5rem * var(--density-factor))` }}
            variants={staggerContainer(0.03)}
            initial="hidden"
            animate="visible"
          >
            {displayCardIds.map((cardId) => {
              const card = board?.cards[cardId];
              if (!card) return null;
              return (
                <li key={cardId}>
                  <CardThumbnail
                    card={card}
                    boardLabels={board?.labels ?? []}
                    columnId={column.id}
                    onCardClick={onCardClick}
                    isFocused={focusedCardId === cardId}
                  />
                </li>
              );
            })}
            {displayCardIds.length === 0 && (
              <li className="flex min-h-[60px] items-center justify-center rounded-md border border-dashed border-pylon-text-secondary/20 text-xs text-pylon-text-secondary/50">
                {isFiltering ? "No matching cards" : "Drop or add a card"}
              </li>
            )}
          </motion.ul>
        </OverlayScrollbarsComponent>
      </SortableContext>

      {/* Add card section */}
      {showAddCard ? (
        <AddCardInput
          columnId={column.id}
          onClose={() => setShowAddCard(false)}
        />
      ) : (
        <div className="p-2">
          <Button
            variant="ghost"
            size="sm"
            onClick={() => setShowAddCard(true)}
            className="w-full justify-start text-pylon-text-secondary hover:text-pylon-text"
          >
            <Plus className="size-4" />
            Add card
          </Button>
        </div>
      )}
    </motion.section>
    )}
    </motion.div>
  );
}
