"use client";

import { useState, useCallback } from "react";
import {
  DndContext,
  DragOverlay,
  PointerSensor,
  useSensor,
  useSensors,
  type DragStartEvent,
  type DragEndEvent,
} from "@dnd-kit/core";
import { useDroppable } from "@dnd-kit/core";
import { useRouter } from "next/navigation";
import { useToast } from "@/components/ui/use-toast";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { KanbanCard } from "./KanbanCard";
import { TASK_STATUS_CONFIG } from "./TaskCard";
import { updateTaskStatus } from "@/actions/tasks";
import { TaskStatus, TaskType } from "@prisma/client";
import { cn } from "@/lib/utils";

const COLUMN_ORDER: TaskStatus[] = [
  "TODO",
  "IN_PROGRESS",
  "INTERNAL_REVIEW",
  "CLIENT_REVIEW",
  "CHANGES",
  "DONE",
];

interface KanbanTask {
  id: string;
  title: string;
  type: TaskType;
  status: TaskStatus;
  priority: string;
  dueDate: Date | null;
  shot?: { shotCode: string } | null;
  asset?: { assetCode: string; name: string } | null;
  assignedArtist?: {
    id: string;
    name: string | null;
    email: string;
    image: string | null;
  } | null;
  _count?: { versions: number };
  versions?: {
    id: string;
    versionNumber: number;
    approvalStatus: string;
    createdAt: Date;
  }[];
}

function KanbanColumn({
  status,
  tasks,
}: {
  status: TaskStatus;
  tasks: KanbanTask[];
}) {
  const { setNodeRef, isOver } = useDroppable({ id: status });
  const cfg = TASK_STATUS_CONFIG[status];
  const Icon = cfg.icon;

  return (
    <div className="flex flex-col min-w-[240px] w-[240px] shrink-0">
      {/* Column header */}
      <div className="flex items-center gap-2 mb-3 px-1">
        <Icon className="h-3.5 w-3.5 text-zinc-500" />
        <span className="text-xs font-semibold text-zinc-400 uppercase tracking-wider">
          {cfg.label}
        </span>
        <span className="ml-auto text-xs text-zinc-600 bg-zinc-800 rounded-full px-1.5 py-0.5 font-mono">
          {tasks.length}
        </span>
      </div>

      {/* Drop zone */}
      <div
        ref={setNodeRef}
        className={cn(
          "flex-1 flex flex-col gap-2 rounded-xl p-2 min-h-[200px] transition-colors",
          isOver ? "bg-zinc-800/60 ring-1 ring-amber-500/30" : "bg-zinc-900/40"
        )}
      >
        {tasks.map((task) => (
          <KanbanCard key={task.id} task={task} />
        ))}

        {tasks.length === 0 && (
          <div className="flex-1 flex items-center justify-center">
            <p className="text-xs text-zinc-700">Drop here</p>
          </div>
        )}
      </div>
    </div>
  );
}

interface KanbanBoardProps {
  tasks: KanbanTask[];
  projectId: string;
  artists?: { id: string; name: string | null; email: string }[];
}

export function KanbanBoard({ tasks: initialTasks, projectId, artists = [] }: KanbanBoardProps) {
  const [tasks, setTasks] = useState<KanbanTask[]>(initialTasks);
  const [draggingTask, setDraggingTask] = useState<KanbanTask | null>(null);
  const [filterArtist, setFilterArtist] = useState<string>("__all__");
  const { toast } = useToast();
  const router = useRouter();

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

  const filteredTasks =
    filterArtist === "__all__"
      ? tasks
      : tasks.filter((t) => t.assignedArtist?.id === filterArtist);

  const columns = COLUMN_ORDER.map((status) => ({
    status,
    tasks: filteredTasks.filter((t) => t.status === status),
  }));

  const handleDragStart = useCallback(
    (event: DragStartEvent) => {
      const task = tasks.find((t) => t.id === event.active.id);
      if (task) setDraggingTask(task);
    },
    [tasks]
  );

  const handleDragEnd = useCallback(
    async (event: DragEndEvent) => {
      setDraggingTask(null);
      const { active, over } = event;
      if (!over || active.id === over.id) return;

      const taskId = active.id as string;
      const newStatus = over.id as TaskStatus;

      // Validate target is a column
      if (!COLUMN_ORDER.includes(newStatus)) return;

      const task = tasks.find((t) => t.id === taskId);
      if (!task || task.status === newStatus) return;

      // Optimistic update
      setTasks((prev) =>
        prev.map((t) => (t.id === taskId ? { ...t, status: newStatus } : t))
      );

      try {
        await updateTaskStatus(taskId, newStatus);
        router.refresh();
      } catch {
        // Revert on failure
        setTasks((prev) =>
          prev.map((t) => (t.id === taskId ? { ...t, status: task.status } : t))
        );
        toast({ title: "Failed to update task status", variant: "destructive" });
      }
    },
    [tasks, router, toast]
  );

  return (
    <DndContext
      sensors={sensors}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      {/* Artist filter */}
      {artists.length > 0 && (
        <div className="flex items-center gap-3 mb-4">
          <span className="text-xs text-zinc-500 font-medium">Filter by artist:</span>
          <Select value={filterArtist} onValueChange={setFilterArtist}>
            <SelectTrigger className="w-44 h-8 text-sm">
              <SelectValue placeholder="All artists" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__all__">All artists</SelectItem>
              {artists.map((a) => (
                <SelectItem key={a.id} value={a.id}>
                  {a.name ?? a.email}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          {filterArtist !== "__all__" && (
            <button
              onClick={() => setFilterArtist("__all__")}
              className="text-xs text-zinc-500 hover:text-zinc-300 transition-colors"
            >
              Clear
            </button>
          )}
        </div>
      )}

      <div className="flex gap-4 overflow-x-auto pb-4 min-h-[400px]">
        {columns.map(({ status, tasks: colTasks }) => (
          <KanbanColumn key={status} status={status} tasks={colTasks} />
        ))}
      </div>

      <DragOverlay dropAnimation={null}>
        {draggingTask && <KanbanCard task={draggingTask} isDragOverlay />}
      </DragOverlay>
    </DndContext>
  );
}
