import { LoadingSpinner } from "@ui/components/LoadingSpinner";
import type { KanbanColumn, KanbanTask } from "@xtablo/shared-types";
import { Button } from "@xtablo/ui/components/button";
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@xtablo/ui/components/dropdown-menu";
import {
  CalendarIcon,
  CircleCheckIcon,
  CircleIcon,
  Compass,
  EllipsisVerticalIcon,
  Flame,
  FolderIcon,
  Gem,
  Heart,
  KanbanIcon,
  Leaf,
  ListIcon,
  ListTodo,
  MapIcon,
  MessageSquareIcon,
  PaperclipIcon,
  PlusIcon,
  Settings2Icon,
  Sparkles,
  Star,
  Sun,
  UserIcon,
  Waves,
  Zap,
} from "lucide-react";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useSearchParams } from "react-router-dom";
import { twMerge } from "tailwind-merge";
import { GanttChart } from "../components/gantt/GanttChart";
import { TaskModal } from "../components/kanban/TaskModal";
import { useTablosList } from "../hooks/tablos";
import { useAllTasks, useUpdateTask } from "../hooks/tasks";
import { useUser } from "../providers/UserStoreProvider";

type TaskStatus = "all" | "todo" | "in_progress" | "in_review" | "done";

type TaskWithTablo = KanbanTask & {
  tablos: { id: string; name: string; color: string | null } | null;
};

const statusLabels: Record<TaskStatus, string> = {
  all: "Tous",
  todo: "À faire",
  in_progress: "En cours",
  in_review: "Vérification",
  done: "Terminé",
};

const columnTitles = {
  todo: "À faire",
  in_progress: "En cours",
  in_review: "Vérification",
  done: "Terminé",
};

function getTabloIcon(color: string | null | undefined) {
  switch (color) {
    case "bg-blue-500":
      return Zap;
    case "bg-green-500":
      return Leaf;
    case "bg-purple-500":
      return Gem;
    case "bg-red-500":
      return Flame;
    case "bg-yellow-500":
      return Star;
    case "bg-indigo-500":
      return Compass;
    case "bg-pink-500":
      return Heart;
    case "bg-teal-500":
      return Waves;
    case "bg-orange-500":
      return Sun;
    case "bg-cyan-500":
      return Sparkles;
    default:
      return FolderIcon;
  }
}

// Light backgrounds need dark text; dark/saturated backgrounds use white
function getTabloIconColor(color: string | null | undefined): string {
  switch (color) {
    case "bg-yellow-500":
    case "bg-cyan-500":
      return "text-gray-700";
    default:
      return "text-white";
  }
}

export function TasksPage() {
  const navigate = useNavigate();
  const { t } = useTranslation(["pages", "common"]);
  const user = useUser();
  const [searchParams, setSearchParams] = useSearchParams();
  const [selectedTabloId, setSelectedTabloId] = useState<string>("all");
  const [statusFilter, setStatusFilter] = useState<TaskStatus>("all");
  const [assigneeFilter, setAssigneeFilter] = useState<string>("all");
  const [isTaskModalOpen, setIsTaskModalOpen] = useState(false);
  const [taskModalInitialDueDate, setTaskModalInitialDueDate] = useState<Date | undefined>(
    undefined
  );
  const searchQuery = searchParams.get("q") ?? "";

  // Get view mode from URL params, default to "kanban"
  const viewMode = (searchParams.get("view") as "kanban" | "aggregated" | "roadmap") || "kanban";

  // Function to update view mode in URL
  const setViewMode = (mode: "kanban" | "aggregated" | "roadmap") => {
    const newParams = new URLSearchParams(searchParams);
    newParams.set("view", mode);
    setSearchParams(newParams);
  };

  // Fetch data
  const { data: tablos, isLoading: tablosLoading } = useTablosList();
  const { data: allTasks = [], isLoading: tasksLoading } = useAllTasks();

  // Mutation for updating task status
  const updateTaskMutation = useUpdateTask();

  const openTaskModal = (dueDate?: Date) => {
    setTaskModalInitialDueDate(dueDate ? new Date(dueDate) : undefined);
    setIsTaskModalOpen(true);
  };

  const closeTaskModal = () => {
    setIsTaskModalOpen(false);
    setTaskModalInitialDueDate(undefined);
  };

  // Filter and search tasks
  const filteredTasks = useMemo(() => {
    let filtered = allTasks as TaskWithTablo[];

    // Tablo filter
    if (selectedTabloId !== "all") {
      filtered = filtered.filter((task) => task.tablo_id === selectedTabloId);
    }

    // Status filter (only applies if not "all")
    if (statusFilter !== "all") {
      filtered = filtered.filter((task) => task.status === statusFilter);
    }

    // Assignee filter
    if (assigneeFilter !== "all") {
      if (assigneeFilter === "me") {
        filtered = filtered.filter((task) => task.assignee_id === user.id);
      } else if (assigneeFilter === "unassigned") {
        filtered = filtered.filter((task) => !task.assignee_id);
      } else {
        filtered = filtered.filter((task) => task.assignee_id === assigneeFilter);
      }
    }

    // Search query
    if (searchQuery.trim()) {
      const q = searchQuery.toLowerCase();
      filtered = filtered.filter(
        (task) =>
          task.title?.toLowerCase().includes(q) || task.description?.toLowerCase().includes(q)
      );
    }

    return filtered;
  }, [allTasks, selectedTabloId, statusFilter, assigneeFilter, user.id, searchQuery]);

  // Initialize Kanban columns from filtered tasks
  const columns = useMemo((): KanbanColumn[] => {
    const defaultColumns: KanbanColumn[] = [
      {
        id: "todo",
        title: columnTitles.todo,
        status: "todo",
        position: 0,
        tasks: filteredTasks.filter((task) => task.status === "todo"),
      },
      {
        id: "in_progress",
        title: columnTitles.in_progress,
        status: "in_progress",
        position: 1,
        tasks: filteredTasks.filter((task) => task.status === "in_progress"),
      },
      {
        id: "in_review",
        title: columnTitles.in_review,
        status: "in_review",
        position: 2,
        tasks: filteredTasks.filter((task) => task.status === "in_review"),
      },
      {
        id: "done",
        title: columnTitles.done,
        status: "done",
        position: 3,
        tasks: filteredTasks.filter((task) => task.status === "done"),
      },
    ];
    return defaultColumns;
  }, [filteredTasks]);

  // Get unique assignees from tasks
  const assignees = useMemo(() => {
    const assigneeMap = new Map<string, { id: string; name: string }>();
    allTasks.forEach((task) => {
      if (task.assignee_id && task.assignee_name) {
        if (!assigneeMap.has(task.assignee_id)) {
          assigneeMap.set(task.assignee_id, {
            id: task.assignee_id,
            name: task.assignee_name,
          });
        }
      }
    });
    return Array.from(assigneeMap.values());
  }, [allTasks]);

  const handleTaskClick = (task: KanbanTask) => {
    if (task.tablo_id) {
      navigate(`/tablos/${task.tablo_id}?section=tasks`);
    }
  };

  const handleDragStart = (e: React.DragEvent, task: KanbanTask) => {
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("taskId", task.id);
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
  };

  const handleDrop = (
    e: React.DragEvent,
    targetStatus: "todo" | "in_progress" | "in_review" | "done"
  ) => {
    e.preventDefault();
    const taskId = e.dataTransfer.getData("taskId");

    if (!taskId) return;

    // Find the task to update
    const task = filteredTasks.find((t) => t.id === taskId);
    if (!task || task.status === targetStatus) return;

    // Update the task status
    updateTaskMutation.mutate({
      id: taskId,
      status: targetStatus,
    });
  };

  const viewTabs = [
    { id: "kanban" as const, label: "Tableau", icon: KanbanIcon },
    { id: "aggregated" as const, label: "Liste", icon: ListIcon },
    { id: "roadmap" as const, label: "Roadmap", icon: MapIcon },
    {
      id: "calendar" as const,
      label: "Calendrier",
      icon: CalendarIcon,
      disabled: true,
      comingSoon: true,
    },
  ];

  return (
    <div className="min-h-screen">
      {/* Header */}
      <div className="px-4 md:px-6 pt-6 md:pt-10 pb-5">
        {/* Title row */}
        <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-4">
          <h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
            {t("pages:tasks.title")}
          </h1>
          <Button
            onClick={() => openTaskModal()}
            className="bg-purple-600 hover:bg-purple-700 text-white w-full md:w-auto gap-2"
          >
            <PlusIcon className="w-4 h-4" />
            {t("pages:tasks.createTask")}
          </Button>
        </div>

        {/* View tabs */}
        <div className="flex flex-wrap items-center gap-2 md:gap-6 mb-4 border-b border-[#EAECF0] dark:border-gray-700">
          {viewTabs.map((tab) => {
            const isActive = viewMode === tab.id;
            return (
              <button
                key={tab.id}
                type="button"
                disabled={tab.disabled}
                onClick={() =>
                  !tab.disabled && setViewMode(tab.id as "kanban" | "aggregated" | "roadmap")
                }
                className={twMerge(
                  "flex items-center gap-2 pb-3 px-1 text-sm font-semibold transition-colors border-b-2",
                  isActive
                    ? "text-purple-600 border-purple-600 dark:text-purple-400 dark:border-purple-400"
                    : "text-[#667085] border-transparent hover:text-gray-900 dark:hover:text-gray-100",
                  tab.disabled && "cursor-not-allowed"
                )}
              >
                <tab.icon className={twMerge("w-4 h-4", tab.disabled && "opacity-40")} />
                <span className={tab.disabled ? "opacity-40" : ""}>{tab.label}</span>
                {"comingSoon" in tab && tab.comingSoon && (
                  <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 leading-none">
                    Bientôt
                  </span>
                )}
              </button>
            );
          })}
        </div>

        {/* Filter row */}
        <div className="flex flex-col md:flex-row md:items-center md:justify-end gap-3">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="outline" className="w-full md:w-auto gap-2 bg-transparent">
                <Settings2Icon className="w-4 h-4" />
                Filtrer
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-56">
              <DropdownMenuLabel>Projet</DropdownMenuLabel>
              <DropdownMenuSeparator />
              <DropdownMenuCheckboxItem
                checked={selectedTabloId === "all"}
                onCheckedChange={() => setSelectedTabloId("all")}
              >
                Tous les projets
              </DropdownMenuCheckboxItem>
              {tablos?.map((tablo) => (
                <DropdownMenuCheckboxItem
                  key={tablo.id}
                  checked={selectedTabloId === tablo.id}
                  onCheckedChange={() => setSelectedTabloId(tablo.id)}
                >
                  <div className="flex items-center gap-2">
                    <div
                      className={twMerge(
                        "w-2 h-2 rounded-full shrink-0",
                        tablo.color || "bg-gray-400"
                      )}
                    />
                    {tablo.name}
                  </div>
                </DropdownMenuCheckboxItem>
              ))}
              <DropdownMenuSeparator />
              <DropdownMenuLabel>Statut</DropdownMenuLabel>
              <DropdownMenuSeparator />
              {Object.entries(statusLabels).map(([value, label]) => (
                <DropdownMenuCheckboxItem
                  key={value}
                  checked={statusFilter === value}
                  onCheckedChange={() => setStatusFilter(value as TaskStatus)}
                >
                  {label}
                </DropdownMenuCheckboxItem>
              ))}
              <DropdownMenuSeparator />
              <DropdownMenuLabel>Assigné</DropdownMenuLabel>
              <DropdownMenuSeparator />
              <DropdownMenuCheckboxItem
                checked={assigneeFilter === "all"}
                onCheckedChange={() => setAssigneeFilter("all")}
              >
                Tous
              </DropdownMenuCheckboxItem>
              <DropdownMenuCheckboxItem
                checked={assigneeFilter === "me"}
                onCheckedChange={() => setAssigneeFilter("me")}
              >
                Assigné à moi
              </DropdownMenuCheckboxItem>
              <DropdownMenuCheckboxItem
                checked={assigneeFilter === "unassigned"}
                onCheckedChange={() => setAssigneeFilter("unassigned")}
              >
                Non assigné
              </DropdownMenuCheckboxItem>
              {assignees.map((assignee) => (
                <DropdownMenuCheckboxItem
                  key={assignee.id}
                  checked={assigneeFilter === assignee.id}
                  onCheckedChange={() => setAssigneeFilter(assignee.id)}
                >
                  {assignee.name}
                </DropdownMenuCheckboxItem>
              ))}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </div>

      {/* Main Content */}
      <main className="px-4 md:px-6 pb-6">
        {viewMode === "roadmap" ? (
          <RoadmapView
            tasks={filteredTasks}
            isLoading={tablosLoading || tasksLoading}
            onDateClick={openTaskModal}
            onTaskStatusChange={(taskId, status) =>
              updateTaskMutation.mutate({ id: taskId, status })
            }
          />
        ) : viewMode === "kanban" ? (
          /* Kanban Board */
          <>
            {tablosLoading || tasksLoading ? (
              <div className="flex items-center justify-center h-64">
                <LoadingSpinner />
              </div>
            ) : filteredTasks.length === 0 ? (
              <div className="p-12 text-center">
                <ListTodo className="mx-auto h-12 w-12 text-muted-foreground" />
                <h3 className="mt-2 text-sm font-medium text-foreground">
                  {t("pages:tasks.emptyState.title")}
                </h3>
                <p className="mt-1 text-sm text-muted-foreground">
                  {statusFilter !== "all" || selectedTabloId !== "all"
                    ? t("pages:tasks.emptyState.noResults")
                    : t("pages:tasks.emptyState.noTasks")}
                </p>
              </div>
            ) : (
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
                {columns.map((column) => {
                  const columnIconColor =
                    {
                      todo: "text-gray-400",
                      in_progress: "text-yellow-500",
                      in_review: "text-blue-500",
                      done: "text-green-500",
                    }[column.status] ?? "text-gray-400";

                  return (
                    <div
                      key={column.id}
                      className="w-full h-fit bg-[#F9FAFB] dark:bg-gray-800/60 rounded-[12px] p-4"
                    >
                      {/* Column header */}
                      <div className="flex items-center justify-between mb-4">
                        <div className="flex items-center space-x-2">
                          <CircleIcon className={`w-5 h-5 ${columnIconColor}`} />
                          <h2 className="font-semibold text-gray-800 dark:text-gray-100">
                            {column.title}
                          </h2>
                          <span className="bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 text-xs font-medium px-2 py-0.5 rounded-full">
                            {column.tasks.length}
                          </span>
                        </div>
                        <button
                          type="button"
                          onClick={() => openTaskModal()}
                          className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700 rounded p-1 transition-colors"
                        >
                          <PlusIcon className="w-[18px] h-[18px]" />
                        </button>
                      </div>

                      {/* Task cards */}
                      <div
                        className="space-y-3 pr-1 min-h-[80px]"
                        onDragOver={handleDragOver}
                        onDrop={(e) => handleDrop(e, column.status)}
                      >
                        {column.tasks.length === 0 ? (
                          <div className="flex items-center justify-center h-20 text-gray-400 dark:text-gray-500 text-sm">
                            {t("pages:tasks.emptyState.noTasks")}
                          </div>
                        ) : (
                          column.tasks.map((task) => {
                            const taskWithTablo = task as TaskWithTablo;
                            const formattedDate = task.due_date
                              ? new Intl.DateTimeFormat("fr-FR", {
                                  month: "short",
                                  day: "2-digit",
                                }).format(new Date(task.due_date))
                              : null;
                            const isOverdue =
                              task.due_date &&
                              task.status !== "done" &&
                              new Date(task.due_date) < new Date(new Date().toDateString());

                            return (
                              <div
                                key={task.id}
                                draggable
                                onDragStart={(e) => handleDragStart(e, task)}
                                onClick={() => handleTaskClick(task)}
                                className="bg-white dark:bg-gray-800 rounded-lg p-4 mb-3 shadow-sm hover:shadow-md transition-shadow border border-gray-100 dark:border-gray-700 cursor-pointer"
                              >
                                {/* Title + kebab */}
                                <div className="flex items-start justify-between gap-2 mb-2">
                                  <h3 className="font-semibold text-gray-900 dark:text-gray-100 text-sm leading-tight line-clamp-2 flex-1">
                                    {task.title}
                                  </h3>
                                  <DropdownMenu>
                                    <DropdownMenuTrigger asChild>
                                      <button
                                        type="button"
                                        onClick={(e) => e.stopPropagation()}
                                        className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 shrink-0 mt-0.5"
                                      >
                                        <EllipsisVerticalIcon className="w-4 h-4" />
                                      </button>
                                    </DropdownMenuTrigger>
                                    <DropdownMenuContent align="end" className="w-48">
                                      <DropdownMenuItem
                                        onClick={(e) => {
                                          e.stopPropagation();
                                          handleTaskClick(task);
                                        }}
                                      >
                                        Ouvrir la tâche
                                      </DropdownMenuItem>
                                      <DropdownMenuSeparator />
                                      <DropdownMenuLabel>Déplacer vers</DropdownMenuLabel>
                                      {(["todo", "in_progress", "in_review", "done"] as const)
                                        .filter((s) => s !== task.status)
                                        .map((s) => (
                                          <DropdownMenuItem
                                            key={s}
                                            onClick={(e) => {
                                              e.stopPropagation();
                                              updateTaskMutation.mutate({
                                                id: task.id,
                                                status: s,
                                              });
                                            }}
                                          >
                                            {columnTitles[s]}
                                          </DropdownMenuItem>
                                        ))}
                                    </DropdownMenuContent>
                                  </DropdownMenu>
                                </div>

                                {formattedDate && (
                                  <div
                                    className={twMerge(
                                      "flex items-center text-xs mb-3",
                                      isOverdue
                                        ? "text-red-500"
                                        : "text-gray-500 dark:text-gray-400"
                                    )}
                                  >
                                    <CalendarIcon className="w-3.5 h-3.5 mr-1.5" />
                                    {formattedDate}
                                  </div>
                                )}

                                {/* Tablo row */}
                                {taskWithTablo.tablos &&
                                  (() => {
                                    const TabloIcon = getTabloIcon(taskWithTablo.tablos.color);
                                    const iconColor = getTabloIconColor(taskWithTablo.tablos.color);
                                    return (
                                      <div className="flex items-center mb-3 border-b border-dashed border-[#D0D5DD] dark:border-gray-600 pb-3">
                                        <div
                                          className={twMerge(
                                            "w-5 h-5 rounded-[5px] mr-2 flex items-center justify-center shrink-0",
                                            taskWithTablo.tablos.color || "bg-gray-400"
                                          )}
                                        >
                                          <TabloIcon className={twMerge("w-3 h-3", iconColor)} />
                                        </div>
                                        <span className="text-xs text-gray-600 dark:text-gray-400 truncate">
                                          {taskWithTablo.tablos.name}
                                        </span>
                                      </div>
                                    );
                                  })()}

                                {/* Footer: stats + assignee */}
                                <div className="flex items-center justify-between">
                                  <div className="flex items-center space-x-3 text-gray-500 dark:text-gray-400">
                                    <div className="flex items-center text-xs">
                                      <MessageSquareIcon className="w-3.5 h-3.5 mr-1" />0
                                    </div>
                                    <div className="flex items-center text-xs">
                                      <PaperclipIcon className="w-3.5 h-3.5 mr-1" />0
                                    </div>
                                  </div>

                                  {/* Assignee avatar */}
                                  <div className="flex -space-x-2">
                                    {task.assignee_id ? (
                                      task.assignee_avatar ? (
                                        <img
                                          src={task.assignee_avatar}
                                          alt={task.assignee_name || "Assignee"}
                                          className="w-6 h-6 rounded-full border-2 border-white dark:border-gray-800 object-cover"
                                        />
                                      ) : (
                                        <div className="w-6 h-6 rounded-full bg-purple-500 border-2 border-white dark:border-gray-800 flex items-center justify-center text-white text-[10px] font-medium">
                                          {task.assignee_name?.charAt(0).toUpperCase() || (
                                            <UserIcon className="w-3 h-3" />
                                          )}
                                        </div>
                                      )
                                    ) : (
                                      <div className="w-6 h-6 rounded-full bg-gray-200 dark:bg-gray-600 border-2 border-white dark:border-gray-800 flex items-center justify-center">
                                        <UserIcon className="w-3 h-3 text-gray-400 dark:text-gray-300" />
                                      </div>
                                    )}
                                  </div>
                                </div>
                              </div>
                            );
                          })
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </>
        ) : (
          /* List View — grouped by status column */
          <>
            {tablosLoading || tasksLoading ? (
              <div className="flex items-center justify-center h-64">
                <LoadingSpinner />
              </div>
            ) : filteredTasks.length === 0 ? (
              <div className="p-12 text-center">
                <ListTodo className="mx-auto h-12 w-12 text-muted-foreground" />
                <h3 className="mt-2 text-sm font-medium text-foreground">
                  {t("pages:tasks.emptyState.title")}
                </h3>
                <p className="mt-1 text-sm text-muted-foreground">
                  {statusFilter !== "all" || selectedTabloId !== "all"
                    ? t("pages:tasks.emptyState.noResults")
                    : t("pages:tasks.emptyState.noTasks")}
                </p>
              </div>
            ) : (
              <div className="space-y-6">
                {columns.map((column) => {
                  if (column.tasks.length === 0) return null;
                  const columnIconColor =
                    {
                      todo: "text-gray-400",
                      in_progress: "text-yellow-500",
                      in_review: "text-blue-500",
                      done: "text-green-500",
                    }[column.status] ?? "text-gray-400";

                  return (
                    <div
                      key={column.id}
                      className="bg-[#F9FAFB] dark:bg-gray-800/60 rounded-lg p-2"
                    >
                      {/* Column header */}
                      <div className="px-4 md:px-6 py-3 flex items-center justify-between">
                        <div className="flex items-center gap-2">
                          <CircleIcon className={`w-5 h-5 ${columnIconColor}`} />
                          <h3 className="font-semibold text-gray-900 dark:text-gray-100">
                            {column.title}
                          </h3>
                          <span className="text-xs bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 px-2 py-1 rounded-full">
                            {column.tasks.length}
                          </span>
                        </div>
                        <button
                          type="button"
                          onClick={() => openTaskModal()}
                          className="inline-flex items-center gap-1 h-8 px-3 text-xs font-medium rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
                        >
                          <PlusIcon className="w-4 h-4 text-gray-600 dark:text-gray-400" />
                        </button>
                      </div>

                      {/* Table */}
                      <div className="overflow-x-auto bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700">
                        <table className="w-full table-fixed min-w-[700px]">
                          <colgroup>
                            <col className="w-[35%]" />
                            <col className="w-[25%]" />
                            <col className="w-[15%]" />
                            <col className="w-[12%]" />
                            <col className="w-[8%]" />
                          </colgroup>
                          <thead>
                            <tr>
                              <th className="px-4 md:px-6 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-400">
                                TÂCHE
                              </th>
                              <th className="px-4 md:px-6 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-400">
                                PROJET
                              </th>
                              <th className="px-4 md:px-6 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-400">
                                ÉCHÉANCE
                              </th>
                              <th className="px-4 md:px-6 py-3 text-left text-xs font-semibold text-gray-700 dark:text-gray-400">
                                PERSONNES
                              </th>
                              <th className="px-4 md:px-6 py-3 text-right text-xs font-semibold text-gray-700 dark:text-gray-400" />
                            </tr>
                          </thead>
                          <tbody>
                            {column.tasks.map((task) => {
                              const taskWithTablo = task as TaskWithTablo;
                              return (
                                <tr
                                  key={task.id}
                                  className="border-t border-gray-100 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors cursor-pointer"
                                  onClick={() => handleTaskClick(task)}
                                >
                                  {/* Task name */}
                                  <td className="px-4 md:px-6 py-3">
                                    <div className="flex items-center gap-2">
                                      {column.status === "done" ? (
                                        <CircleCheckIcon className="w-5 h-5 text-green-500 shrink-0" />
                                      ) : (
                                        <div className="w-5 h-5 border-2 border-gray-300 dark:border-gray-600 rounded-full shrink-0" />
                                      )}
                                      <span className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
                                        {task.title}
                                      </span>
                                    </div>
                                  </td>

                                  {/* Project */}
                                  <td className="px-4 md:px-6 py-3">
                                    {taskWithTablo.tablos ? (
                                      (() => {
                                        const TabloIcon = getTabloIcon(taskWithTablo.tablos.color);
                                        const iconColor = getTabloIconColor(
                                          taskWithTablo.tablos.color
                                        );
                                        return (
                                          <div className="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
                                            <div
                                              className={twMerge(
                                                "w-5 h-5 rounded-[4px] shrink-0 flex items-center justify-center",
                                                taskWithTablo.tablos.color || "bg-gray-400"
                                              )}
                                            >
                                              <TabloIcon
                                                className={twMerge("w-3 h-3", iconColor)}
                                              />
                                            </div>
                                            <span className="truncate">
                                              {taskWithTablo.tablos.name}
                                            </span>
                                          </div>
                                        );
                                      })()
                                    ) : (
                                      <span className="text-sm text-gray-400">—</span>
                                    )}
                                  </td>

                                  {/* Due date */}
                                  <td className="px-4 md:px-6 py-3">
                                    {task.due_date ? (
                                      (() => {
                                        const dueDateOverdue =
                                          task.status !== "done" &&
                                          new Date(task.due_date) <
                                            new Date(new Date().toDateString());
                                        return (
                                          <div
                                            className={twMerge(
                                              "flex items-center gap-1 text-sm",
                                              dueDateOverdue
                                                ? "text-red-500"
                                                : "text-gray-600 dark:text-gray-400"
                                            )}
                                          >
                                            <CalendarIcon className="w-3.5 h-3.5" />
                                            <span>
                                              {new Intl.DateTimeFormat("fr-FR", {
                                                day: "2-digit",
                                                month: "short",
                                              }).format(new Date(task.due_date))}
                                            </span>
                                          </div>
                                        );
                                      })()
                                    ) : (
                                      <span className="text-sm text-gray-400">—</span>
                                    )}
                                  </td>

                                  {/* Assignee */}
                                  <td className="px-4 md:px-6 py-3">
                                    <div className="flex -space-x-1">
                                      {task.assignee_id ? (
                                        task.assignee_avatar ? (
                                          <img
                                            src={task.assignee_avatar}
                                            alt={task.assignee_name || ""}
                                            title={task.assignee_name || ""}
                                            className="w-6 h-6 rounded-full border border-white dark:border-gray-800 object-cover"
                                          />
                                        ) : (
                                          <div
                                            title={task.assignee_name || ""}
                                            className="w-6 h-6 rounded-full bg-purple-200 dark:bg-purple-900 text-purple-700 dark:text-purple-300 flex items-center justify-center text-xs font-semibold border border-white dark:border-gray-800"
                                          >
                                            {task.assignee_name?.charAt(0).toUpperCase() || (
                                              <UserIcon className="w-3 h-3" />
                                            )}
                                          </div>
                                        )
                                      ) : (
                                        <div className="w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-700 border border-white dark:border-gray-800 flex items-center justify-center">
                                          <UserIcon className="w-3 h-3 text-gray-400" />
                                        </div>
                                      )}
                                    </div>
                                  </td>

                                  {/* Kebab */}
                                  <td className="px-4 md:px-6 py-3 text-right">
                                    <DropdownMenu>
                                      <DropdownMenuTrigger asChild>
                                        <button
                                          type="button"
                                          onClick={(e) => e.stopPropagation()}
                                          className="inline-flex items-center justify-center h-8 w-8 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
                                        >
                                          <EllipsisVerticalIcon className="w-4 h-4 text-gray-400" />
                                        </button>
                                      </DropdownMenuTrigger>
                                      <DropdownMenuContent align="end" className="w-48">
                                        <DropdownMenuItem
                                          onClick={(e) => {
                                            e.stopPropagation();
                                            handleTaskClick(task);
                                          }}
                                        >
                                          Ouvrir la tâche
                                        </DropdownMenuItem>
                                        <DropdownMenuSeparator />
                                        <DropdownMenuLabel>Déplacer vers</DropdownMenuLabel>
                                        {(["todo", "in_progress", "in_review", "done"] as const)
                                          .filter((s) => s !== task.status)
                                          .map((s) => (
                                            <DropdownMenuItem
                                              key={s}
                                              onClick={(e) => {
                                                e.stopPropagation();
                                                updateTaskMutation.mutate({
                                                  id: task.id,
                                                  status: s,
                                                });
                                              }}
                                            >
                                              {columnTitles[s]}
                                            </DropdownMenuItem>
                                          ))}
                                      </DropdownMenuContent>
                                    </DropdownMenu>
                                  </td>
                                </tr>
                              );
                            })}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </>
        )}
      </main>

      {/* Task Create Modal */}
      <TaskModal
        isOpen={isTaskModalOpen}
        onClose={closeTaskModal}
        tablos={tablos}
        allowTabloSelection={true}
        initialStatus="todo"
        initialDueDate={taskModalInitialDueDate}
      />
    </div>
  );
}

// ─── Roadmap View ────────────────────────────────────────────────────────────

type RoadmapTaskWithTablo = KanbanTask & {
  tablos: { id: string; name: string; color: string | null } | null;
};
type RoadmapTaskStatus = "todo" | "in_progress" | "in_review" | "done";

function RoadmapView({
  tasks,
  isLoading,
  onDateClick,
  onTaskStatusChange,
}: {
  tasks: RoadmapTaskWithTablo[];
  isLoading: boolean;
  onDateClick: (date: Date) => void;
  onTaskStatusChange: (taskId: string, status: RoadmapTaskStatus) => void;
}) {
  return (
    <GanttChart
      tasks={tasks}
      isLoading={isLoading}
      onDateClick={onDateClick}
      onTaskStatusChange={onTaskStatusChange}
    />
  );
}
