"use client";

/**
 * Monthly calendar grid with task pills. Drag a task pill to another
 * date to reschedule. Click empty date → quick-create callback.
 */

import { useMemo, useState } from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DndContext, PointerSensor, useSensor, useSensors, type DragEndEvent } from "@dnd-kit/core";
import { useDraggable, useDroppable } from "@dnd-kit/core";

interface Task { id: string; title: string; status: string; dueDate: string | null; priority: string; pipelineStage?: string | null }
interface Props { tasks: Task[]; onReschedule: (taskId: string, date: string) => void; onClickTask: (id: string) => void; onClickDate: (date: string) => void }

const STATUS_CLS: Record<string, string> = { todo: "bg-slate-200 text-slate-700", in_progress: "bg-blue-100 text-blue-800", in_review: "bg-amber-100 text-amber-800", completed: "bg-green-100 text-green-800", overdue: "bg-red-100 text-red-800" };
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

function getMonthDays(year: number, month: number): { date: string; inMonth: boolean }[] {
  const first = new Date(year, month, 1);
  const startDay = first.getDay();
  const days: { date: string; inMonth: boolean }[] = [];
  for (let i = -startDay; days.length < 42; i++) {
    const d = new Date(year, month, 1 + i);
    days.push({ date: d.toISOString().split("T")[0], inMonth: d.getMonth() === month });
  }
  return days;
}

export default function CalendarView({ tasks, onReschedule, onClickTask, onClickDate }: Props) {
  const [viewDate, setViewDate] = useState(() => new Date());
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
  const today = new Date().toISOString().split("T")[0];
  const days = useMemo(() => getMonthDays(viewDate.getFullYear(), viewDate.getMonth()), [viewDate]);

  const tasksByDate = useMemo(() => {
    const map = new Map<string, Task[]>();
    for (const t of tasks) { if (!t.dueDate) continue; const d = new Date(t.dueDate).toISOString().split("T")[0]; map.set(d, [...(map.get(d) || []), t]); }
    return map;
  }, [tasks]);

  function handleDragEnd(e: DragEndEvent) {
    if (!e.over) return;
    onReschedule(String(e.active.id), String(e.over.id));
  }

  function prev() { setViewDate(new Date(viewDate.getFullYear(), viewDate.getMonth() - 1)); }
  function next() { setViewDate(new Date(viewDate.getFullYear(), viewDate.getMonth() + 1)); }

  return (
    <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
      <div className="px-5 py-3 border-b border-slate-100 flex items-center justify-between">
        <button onClick={prev} className="p-1.5 rounded-lg hover:bg-slate-100"><ChevronLeft className="w-4 h-4" /></button>
        <span className="text-sm font-bold text-slate-900">{viewDate.toLocaleDateString("en-US", { month: "long", year: "numeric" })}</span>
        <button onClick={next} className="p-1.5 rounded-lg hover:bg-slate-100"><ChevronRight className="w-4 h-4" /></button>
      </div>
      <DndContext sensors={sensors} onDragEnd={handleDragEnd}>
        <div className="grid grid-cols-7">
          {DAYS.map((d) => <div key={d} className="px-2 py-2 text-center text-[10px] font-bold uppercase tracking-widest text-slate-400 border-b border-slate-100">{d}</div>)}
          {days.map((day) => (
            <DayCell key={day.date} date={day.date} inMonth={day.inMonth} isToday={day.date === today} tasks={tasksByDate.get(day.date) || []} onClickTask={onClickTask} onClickDate={onClickDate} />
          ))}
        </div>
      </DndContext>
    </div>
  );
}

function DayCell({ date, inMonth, isToday, tasks, onClickTask, onClickDate }: { date: string; inMonth: boolean; isToday: boolean; tasks: Task[]; onClickTask: (id: string) => void; onClickDate: (date: string) => void }) {
  const { setNodeRef, isOver } = useDroppable({ id: date });
  const day = new Date(date + "T12:00:00").getDate();
  return (
    <div ref={setNodeRef} onClick={() => tasks.length === 0 && onClickDate(date)} className={`min-h-[80px] px-1.5 py-1 border-b border-r border-slate-100 ${!inMonth ? "bg-slate-50/50" : ""} ${isOver ? "bg-brand-50" : ""} cursor-pointer`}>
      <span className={`inline-flex items-center justify-center w-6 h-6 text-[11px] font-semibold rounded-full mb-0.5 ${isToday ? "bg-brand-600 text-white" : inMonth ? "text-slate-700" : "text-slate-400"}`}>{day}</span>
      <div className="space-y-0.5">
        {tasks.slice(0, 3).map((t) => <TaskPill key={t.id} task={t} onClick={() => onClickTask(t.id)} />)}
        {tasks.length > 3 && <span className="text-[9px] text-slate-400 pl-1">+{tasks.length - 3} more</span>}
      </div>
    </div>
  );
}

function TaskPill({ task, onClick }: { task: Task; onClick: () => void }) {
  const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({ id: task.id });
  const now = new Date();
  const overdue = task.dueDate && new Date(task.dueDate) < now && task.status !== "completed";
  const status = overdue ? "overdue" : task.status;
  const cls = STATUS_CLS[status] || STATUS_CLS.todo;
  const style = transform ? { transform: `translate(${transform.x}px, ${transform.y}px)`, opacity: isDragging ? 0.5 : 1 } : undefined;
  return (
    <div ref={setNodeRef} {...attributes} {...listeners} style={style} onClick={(e) => { e.stopPropagation(); onClick(); }} className={`text-[10px] font-medium rounded px-1.5 py-0.5 truncate cursor-grab ${cls}`} title={task.title}>
      {task.title}
    </div>
  );
}
