import { pluralize, toast } from "@xtablo/shared";
import { UserTablo } from "@xtablo/shared/types/tablos.types";
import type { KanbanColumn, KanbanTask, KanbanTaskInsert, TaskStatus } from "@xtablo/shared-types";
import { TypographyH3, TypographyMuted } from "@xtablo/ui/components/typography";
import { AlertTriangle, ListChecks } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTabloMembers } from "../hooks/tablos";
import {
  useCreateTask,
  useTabloEtapes,
  useTasksByTablo,
  useUpdateTaskPositions,
} from "../hooks/tasks";
import { KanbanBoard } from "./kanban/KanbanBoard";
import { TaskModal } from "./kanban/TaskModal";
import { TabloHeaderActions } from "./TabloHeaderActions";

interface TabloTasksSectionProps {
  tablo: UserTablo;
  isAdmin: boolean;
}

export const TabloTasksSection = ({ tablo, isAdmin }: TabloTasksSectionProps) => {
  const { data: members = [] } = useTabloMembers(tablo.id);
  const [columns, setColumns] = useState<KanbanColumn[]>([]);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedTask, setSelectedTask] = useState<KanbanTask | null>(null);
  const [modalStatus, setModalStatus] = useState<TaskStatus>("todo");

  const { data: tasks } = useTasksByTablo(tablo.id);
  const { data: etapes = [] } = useTabloEtapes(tablo.id);
  const { mutate: updateTaskPositions } = useUpdateTaskPositions();
  const { mutate: createTask } = useCreateTask();

  const memberById = useMemo(
    () => new Map(members.map((member) => [member.id, member])),
    [members]
  );

  const tasksWithAssigneeFallback = useMemo(
    () =>
      (tasks ?? []).map((task) => {
        if (!task.assignee_id) {
          return task;
        }

        const assignee = memberById.get(task.assignee_id);
        if (!assignee) {
          return task;
        }

        return {
          ...task,
          assignee_name: task.assignee_name ?? assignee.name,
          assignee_avatar: task.assignee_avatar ?? assignee.avatar_url,
        } satisfies KanbanTask;
      }),
    [memberById, tasks]
  );

  const etapeTitleMap = useMemo(
    () =>
      etapes.reduce<Record<string, string>>((map, etape) => {
        map[etape.id] = etape.title;
        return map;
      }, {}),
    [etapes]
  );

  // Check for tasks without parent (orphaned tasks)
  const orphanedTasks = useMemo(() => {
    return tasksWithAssigneeFallback.filter((task) => !task.parent_task_id);
  }, [tasksWithAssigneeFallback]);

  // Helper functions defined before use
  const initializeColumns = useCallback((tasks: KanbanTask[]): KanbanColumn[] => {
    const defaultColumns: KanbanColumn[] = [
      {
        id: "todo",
        title: "À faire",
        status: "todo",
        position: 0,
        tasks: tasks.filter((task) => task.status === "todo"),
      },
      {
        id: "in_progress",
        title: "En cours",
        status: "in_progress",
        position: 1,
        tasks: tasks.filter((task) => task.status === "in_progress"),
      },
      {
        id: "in_review",
        title: "Vérification",
        status: "in_review",
        position: 2,
        tasks: tasks.filter((task) => task.status === "in_review"),
      },
      {
        id: "done",
        title: "Terminé",
        status: "done",
        position: 3,
        tasks: tasks.filter((task) => task.status === "done"),
      },
    ];
    return defaultColumns;
  }, []);

  useEffect(() => {
    setColumns(initializeColumns(tasksWithAssigneeFallback));
  }, [initializeColumns, tasksWithAssigneeFallback]);

  const handleAddTask = (status: TaskStatus) => {
    setSelectedTask(null);
    setModalStatus(status);
    setIsModalOpen(true);
  };

  const handleCreateTask = (taskData: {
    title: string;
    description: string;
    assignee_id?: string;
    status: TaskStatus;
    parent_task_id?: string | null;
  }) => {
    const newTask: KanbanTaskInsert = {
      id: `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      title: taskData.title,
      description: taskData.description,
      status: taskData.status,
      assignee_id: taskData.assignee_id,
      tablo_id: tablo.id,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
      position: 0,
      parent_task_id: taskData.parent_task_id ?? null,
    };

    createTask(newTask);

    // setColumns((prevColumns) =>
    //   prevColumns.map((column: KanbanColumn) => {
    //     if (column.status === (taskData.status as TaskStatus)) {
    //       return {
    //         ...column,
    //         tasks: [newTask, ...column.tasks],
    //       };
    //     }
    //     return column;
    //   })
    // );

    toast.add(
      {
        title: "Tâche créée",
        description: `La tâche "${taskData.title}" a été créée avec succès`,
        type: "success",
      },
      { timeout: 3000 }
    );
  };

  const handleTaskMove = (taskId: string, newStatus: TaskStatus) => {
    updateTaskPositions([
      {
        id: taskId,
        position: columns.find((column) => column.status === newStatus)?.position ?? 0,
        status: newStatus,
      },
    ]);

    toast.add(
      {
        title: "Tâche déplacée",
        description: "La tâche a été déplacée avec succès",
        type: "success",
      },
      { timeout: 2000 }
    );
  };

  const handleTaskClick = (task: KanbanTask) => {
    setSelectedTask(task);
    setModalStatus(task.status ?? "todo");
    setIsModalOpen(true);
  };

  return (
    <div className="space-y-6">
      <div className="flex items-start justify-between">
        <div>
          <TypographyH3 className="text-3xl font-bold text-foreground flex items-center gap-3">
            <ListChecks className="w-8 h-8" />
            Tâches
          </TypographyH3>
          <TypographyMuted className="text-muted-foreground mt-1">
            Gérez vos tâches avec un tableau Kanban
          </TypographyMuted>
        </div>
        <TabloHeaderActions tablo={tablo} isAdmin={isAdmin} />
      </div>

      {/* Warning for orphaned tasks */}
      {orphanedTasks.length > 0 && (
        <div className="bg-yellow-50 dark:bg-yellow-950/20 border border-yellow-200 dark:border-yellow-900/50 rounded-lg p-4">
          <div className="flex items-start gap-3">
            <AlertTriangle className="h-5 w-5 text-yellow-600 dark:text-yellow-500 shrink-0 mt-0.5" />
            <div>
              <p className="text-sm font-medium text-yellow-800 dark:text-yellow-200">
                {orphanedTasks.length} {pluralize("tâche", orphanedTasks.length)} sans Étape
              </p>
              <p className="text-sm text-yellow-700 dark:text-yellow-300 mt-1">
                {orphanedTasks.length === 1
                  ? "Cette tâche n'est associée à aucune Étape. Modifiez-la pour l'associer à une Étape."
                  : "Ces tâches ne sont associées à aucune Étape. Modifiez-les pour les associer à une Étape."}
              </p>
            </div>
          </div>
        </div>
      )}

      {/* Kanban Board */}
      <div className="bg-card rounded-lg border border-border p-6">
        <KanbanBoard
          columns={columns}
          members={members}
          etapes={etapes}
          etapeTitles={etapeTitleMap}
          onTaskClick={handleTaskClick}
          onAddTask={handleAddTask}
          onAddTaskInline={handleCreateTask}
          onTaskMove={handleTaskMove}
        />
      </div>

      {/* Task Create Modal */}
      <TaskModal
        tabloId={tablo.id}
        taskId={selectedTask?.id}
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        members={members}
        initialStatus={modalStatus}
        etapes={etapes}
      />
    </div>
  );
};
