"use client";

import type { GanttTask, GanttChartProps, TimelineRange, GanttBarPosition } from "./types";
import { TaskStatus } from "@mosaic/shared";
import { formatDate, isPastTarget, isApproachingTarget } from "@/lib/utils/date-format";
import { useMemo } from "react";

/**
 * Calculate the timeline range from a list of tasks
 */
function calculateTimelineRange(tasks: GanttTask[]): TimelineRange {
  if (tasks.length === 0) {
    const now = new Date();
    const oneMonthLater = new Date(now);
    oneMonthLater.setMonth(oneMonthLater.getMonth() + 1);
    
    return {
      start: now,
      end: oneMonthLater,
      totalDays: 30,
    };
  }

  let earliest = tasks[0].startDate;
  let latest = tasks[0].endDate;

  tasks.forEach((task) => {
    if (task.startDate < earliest) {
      earliest = task.startDate;
    }
    if (task.endDate > latest) {
      latest = task.endDate;
    }
  });

  // Add padding (5% on each side)
  const totalMs = latest.getTime() - earliest.getTime();
  const padding = totalMs * 0.05;
  
  const start = new Date(earliest.getTime() - padding);
  const end = new Date(latest.getTime() + padding);
  
  const totalDays = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));

  return { start, end, totalDays };
}

/**
 * Calculate the position and width for a task bar
 */
function calculateBarPosition(
  task: GanttTask,
  timelineRange: TimelineRange,
  rowIndex: number
): GanttBarPosition {
  const { start: rangeStart, totalDays } = timelineRange;
  
  const taskStartOffset = Math.max(
    0,
    (task.startDate.getTime() - rangeStart.getTime()) / (1000 * 60 * 60 * 24)
  );
  
  const taskDuration = Math.max(
    0.5, // Minimum 0.5 day width for visibility
    (task.endDate.getTime() - task.startDate.getTime()) / (1000 * 60 * 60 * 24)
  );
  
  const leftPercent = (taskStartOffset / totalDays) * 100;
  const widthPercent = (taskDuration / totalDays) * 100;

  return {
    left: `${leftPercent}%`,
    width: `${widthPercent}%`,
    top: rowIndex * 48, // 48px row height
  };
}

/**
 * Get CSS class for task status
 */
function getStatusClass(status: TaskStatus): string {
  switch (status) {
    case TaskStatus.COMPLETED:
      return "bg-green-500";
    case TaskStatus.IN_PROGRESS:
      return "bg-blue-500";
    case TaskStatus.PAUSED:
      return "bg-yellow-500";
    case TaskStatus.ARCHIVED:
      return "bg-gray-400";
    default:
      return "bg-gray-500";
  }
}

/**
 * Get CSS class for task row status
 */
function getRowStatusClass(status: TaskStatus): string {
  switch (status) {
    case TaskStatus.COMPLETED:
      return "gantt-row-completed";
    case TaskStatus.IN_PROGRESS:
      return "gantt-row-in-progress";
    case TaskStatus.PAUSED:
      return "gantt-row-paused";
    default:
      return "";
  }
}

/**
 * Generate month labels for the timeline header
 */
function generateTimelineLabels(range: TimelineRange): Array<{ label: string; position: number }> {
  const labels: Array<{ label: string; position: number }> = [];
  const current = new Date(range.start);
  
  // Generate labels for each month in the range
  while (current <= range.end) {
    const position =
      ((current.getTime() - range.start.getTime()) / (1000 * 60 * 60 * 24)) / range.totalDays;
    
    const label = current.toLocaleDateString("en-US", {
      month: "short",
      year: "numeric",
    });
    
    labels.push({ label, position: position * 100 });
    
    // Move to next month
    current.setMonth(current.getMonth() + 1);
  }
  
  return labels;
}

/**
 * Main Gantt Chart Component
 */
export function GanttChart({
  tasks,
  onTaskClick,
  height = 400,
  showDependencies = false,
}: GanttChartProps): JSX.Element {
  // Sort tasks by start date
  const sortedTasks = useMemo(() => {
    return [...tasks].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
  }, [tasks]);

  // Calculate timeline range
  const timelineRange = useMemo(() => calculateTimelineRange(sortedTasks), [sortedTasks]);

  // Generate timeline labels
  const timelineLabels = useMemo(() => generateTimelineLabels(timelineRange), [timelineRange]);

  const handleTaskClick = (task: GanttTask) => (): void => {
    if (onTaskClick) {
      onTaskClick(task);
    }
  };

  const handleKeyDown = (task: GanttTask) => (e: React.KeyboardEvent<HTMLDivElement>): void => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      if (onTaskClick) {
        onTaskClick(task);
      }
    }
  };

  return (
    <div
      role="region"
      aria-label="Gantt Chart"
      className="gantt-chart bg-white rounded-lg border border-gray-200 overflow-hidden"
      style={{ height: `${height}px` }}
    >
      <div className="gantt-container flex h-full">
        {/* Task list column */}
        <div className="gantt-task-list w-64 border-r border-gray-200 overflow-y-auto flex-shrink-0">
          <div className="gantt-task-list-header bg-gray-50 p-3 border-b border-gray-200 font-semibold sticky top-0 z-10">
            Tasks
          </div>
          <div className="gantt-task-list-body">
            {sortedTasks.map((task, index) => {
              const isPast = isPastTarget(task.endDate);
              const isApproaching = !isPast && isApproachingTarget(task.endDate);
              
              return (
                <div
                  key={task.id}
                  role="row"
                  className={`gantt-task-row p-3 border-b border-gray-100 h-12 flex items-center ${getRowStatusClass(
                    task.status
                  )}`}
                >
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-medium text-gray-900 truncate">
                      {task.title}
                    </div>
                    {isPast && task.status !== TaskStatus.COMPLETED && (
                      <div className="text-xs text-amber-600">Target passed</div>
                    )}
                    {isApproaching && task.status !== TaskStatus.COMPLETED && (
                      <div className="text-xs text-orange-600">Approaching target</div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* Timeline column */}
        <div className="gantt-timeline flex-1 overflow-x-auto overflow-y-auto">
          <div role="region" aria-label="Timeline" className="gantt-timeline-container min-w-full">
            {/* Timeline header */}
            <div className="gantt-timeline-header bg-gray-50 border-b border-gray-200 h-12 sticky top-0 z-10 relative">
              {timelineLabels.map((label, index) => (
                <div
                  key={index}
                  className="absolute top-0 bottom-0 flex items-center text-xs text-gray-600 px-2"
                  style={{ left: `${label.position}%` }}
                >
                  {label.label}
                </div>
              ))}
            </div>

            {/* Timeline grid and bars */}
            <div className="gantt-timeline-body relative">
              {/* Grid lines */}
              <div className="gantt-grid absolute inset-0 pointer-events-none">
                {timelineLabels.map((label, index) => (
                  <div
                    key={index}
                    className="absolute top-0 bottom-0 w-px bg-gray-200"
                    style={{ left: `${label.position}%` }}
                  />
                ))}
              </div>

              {/* Task bars */}
              {sortedTasks.map((task, index) => {
                const position = calculateBarPosition(task, timelineRange, index);
                const statusClass = getStatusClass(task.status);
                
                return (
                  <div
                    key={task.id}
                    role="button"
                    tabIndex={0}
                    aria-label={`Gantt bar for ${task.title}, from ${formatDate(
                      task.startDate
                    )} to ${formatDate(task.endDate)}`}
                    className={`gantt-bar absolute h-8 rounded cursor-pointer transition-all hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 ${statusClass}`}
                    style={{
                      left: position.left,
                      width: position.width,
                      top: `${position.top + 8}px`, // Center in row
                    }}
                    onClick={handleTaskClick(task)}
                    onKeyDown={handleKeyDown(task)}
                  >
                    <div className="px-2 text-xs text-white truncate leading-8">
                      {task.title}
                    </div>
                  </div>
                );
              })}

              {/* Spacer for scrolling */}
              <div
                style={{
                  height: `${sortedTasks.length * 48}px`,
                }}
              />
            </div>
          </div>
        </div>
      </div>

      {/* CSS for status classes */}
      <style jsx>{`
        .gantt-row-completed {
          background-color: #f0fdf4;
        }
        .gantt-row-in-progress {
          background-color: #eff6ff;
        }
        .gantt-row-paused {
          background-color: #fefce8;
        }
      `}</style>
    </div>
  );
}
