"use client";

import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import {
  DndContext,
  DragEndEvent,
  DragOverlay,
  PointerSensor,
  KeyboardSensor,
  useSensor,
  useSensors,
  useDroppable,
  useDraggable,
} from "@dnd-kit/core";
import { updateTaskStatus } from "@/app/admin/clients/[id]/actions";
import type { ClientFullDetail } from "@/lib/admin-queries";

type Task = ClientFullDetail["phases"][number]["tasks"][number] & {
  phaseTitle: string;
};
type Status = "todo" | "in_progress" | "done";

const COLUMNS: { id: Status; label: string; headerClass: string; dotClass: string }[] = [
  {
    id: "todo",
    label: "Da fare",
    headerClass: "text-[#71717a]",
    dotClass: "bg-[#d4d4d8]",
  },
  {
    id: "in_progress",
    label: "In corso",
    headerClass: "text-[#1A463C]",
    dotClass: "bg-[#DEF168]",
  },
  {
    id: "done",
    label: "Fatto",
    headerClass: "text-[#1A463C]",
    dotClass: "bg-[#1A463C]",
  },
];

function DroppableColumn({
  id,
  label,
  headerClass,
  dotClass,
  tasks,
  activeId,
}: {
  id: Status;
  label: string;
  headerClass: string;
  dotClass: string;
  tasks: Task[];
  activeId: string | null;
}) {
  const { setNodeRef, isOver } = useDroppable({ id });

  return (
    <div
      ref={setNodeRef}
      className={`flex flex-col rounded-xl border-2 transition-colors ${
        isOver
          ? "border-[#1A463C] bg-[#1A463C]/5"
          : "border-[#e5e7eb] bg-[#f9f9f9]"
      } min-h-[240px]`}
    >
      <div className={`px-4 py-3 flex items-center justify-between ${headerClass}`}>
        <div className="flex items-center gap-2">
          <span className={`w-2 h-2 rounded-full ${dotClass}`} />
          <span className="text-xs font-bold uppercase tracking-wider">{label}</span>
        </div>
        <span className="text-xs font-semibold tabular-nums bg-white rounded-full px-2 py-0.5 border border-[#e5e7eb]">
          {tasks.length}
        </span>
      </div>

      <div className="flex-1 p-3 space-y-2">
        {tasks.map((task) => (
          <DraggableCard
            key={task.id}
            task={task}
            isActive={activeId === task.id}
          />
        ))}
        {tasks.length === 0 && (
          <p className="text-xs text-[#d4d4d8] italic text-center py-10 select-none">
            Nessun task
          </p>
        )}
      </div>
    </div>
  );
}

function DraggableCard({
  task,
  isActive,
}: {
  task: Task;
  isActive: boolean;
}) {
  const { attributes, listeners, setNodeRef, transform, isDragging } =
    useDraggable({ id: task.id });

  const style = transform
    ? { transform: `translate3d(${transform.x}px, ${transform.y}px, 0)` }
    : undefined;

  return (
    <div
      ref={setNodeRef}
      style={style}
      {...listeners}
      {...attributes}
      className={`bg-white rounded-lg border border-[#e5e7eb] px-3 py-2.5 cursor-grab active:cursor-grabbing shadow-sm select-none transition-opacity ${
        isDragging ? "opacity-30" : "hover:border-[#1A463C]/40 hover:shadow"
      }`}
    >
      <p className="text-[10px] font-medium text-[#71717a] uppercase tracking-wide mb-1 truncate">
        {task.phaseTitle}
      </p>
      <p className="text-sm font-medium text-[#1a1a1a] leading-snug">{task.title}</p>
      {task.description && (
        <p className="text-xs text-[#71717a] mt-1 leading-snug line-clamp-2">
          {task.description}
        </p>
      )}
    </div>
  );
}

export function KanbanBoard({
  phases,
  clientId,
}: {
  phases: ClientFullDetail["phases"];
  clientId: string;
}) {
  const router = useRouter();
  const [, startTransition] = useTransition();
  const [activeId, setActiveId] = useState<string | null>(null);

  const [taskStatuses, setTaskStatuses] = useState<Record<string, Status>>(
    () => {
      const map: Record<string, Status> = {};
      for (const phase of phases) {
        for (const task of phase.tasks) {
          map[task.id] = task.status as Status;
        }
      }
      return map;
    }
  );

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

  const allTasks: Task[] = phases.flatMap((phase) =>
    phase.tasks.map((task) => ({ ...task, phaseTitle: phase.title }))
  );

  const tasksByStatus = COLUMNS.reduce(
    (acc, col) => {
      acc[col.id] = allTasks.filter(
        (t) => (taskStatuses[t.id] ?? t.status) === col.id
      );
      return acc;
    },
    {} as Record<Status, Task[]>
  );

  const activeTask = activeId ? allTasks.find((t) => t.id === activeId) : null;

  function handleDragEnd(event: DragEndEvent) {
    const { active, over } = event;
    setActiveId(null);
    if (!over) return;

    const taskId = active.id as string;
    const newStatus = over.id as Status;
    const currentStatus = taskStatuses[taskId];

    if (newStatus === currentStatus) return;
    if (!(["todo", "in_progress", "done"] as string[]).includes(newStatus))
      return;

    setTaskStatuses((prev) => ({ ...prev, [taskId]: newStatus }));

    startTransition(async () => {
      await updateTaskStatus(taskId, clientId, newStatus);
      router.refresh();
    });
  }

  return (
    <DndContext
      sensors={sensors}
      onDragStart={(e) => setActiveId(e.active.id as string)}
      onDragEnd={handleDragEnd}
    >
      <div className="grid grid-cols-3 gap-4">
        {COLUMNS.map((col) => (
          <DroppableColumn
            key={col.id}
            {...col}
            tasks={tasksByStatus[col.id]}
            activeId={activeId}
          />
        ))}
      </div>

      <DragOverlay dropAnimation={null}>
        {activeTask && (
          <div className="bg-white rounded-lg border-2 border-[#1A463C] px-3 py-2.5 shadow-xl rotate-1 pointer-events-none">
            <p className="text-[10px] font-medium text-[#71717a] uppercase tracking-wide mb-1">
              {activeTask.phaseTitle}
            </p>
            <p className="text-sm font-medium text-[#1a1a1a]">
              {activeTask.title}
            </p>
          </div>
        )}
      </DragOverlay>
    </DndContext>
  );
}