"use client"

import { useEffect, useState, type ReactNode } from "react"
import {
  DndContext,
  DragEndEvent,
  DragOverlay,
  DragStartEvent,
  PointerSensor,
  useDroppable,
  useSensor,
  useSensors,
  closestCorners,
} from "@dnd-kit/core"
import {
  SortableContext,
  verticalListSortingStrategy,
  useSortable,
} from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"
import { useRouter } from "next/navigation"
import { useTaskStore, Task } from "@/stores/useTaskStore"
import { Card, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Plus, GripVertical, ChevronDown, ChevronRight, Calendar } from "lucide-react"
import { format, isValid, parseISO } from "date-fns"
import { generateAvatarDataUrl } from "@/lib/avatar"

const priorityColors: Record<string, string> = {
  low: "bg-slate-600",
  medium: "bg-blue-600",
  high: "bg-orange-600",
  urgent: "bg-red-600",
}

const typeLabels: Record<string, string> = {
  idea: "💡",
  task: "📋",
  bug: "🐛",
  research: "🔬",
  plan: "📐",
}

function formatSprintDateRange(startDate?: string, endDate?: string): string {
  if (!startDate || !endDate) return "No dates"
  const start = parseISO(startDate)
  const end = parseISO(endDate)
  if (!isValid(start) || !isValid(end)) return "Invalid dates"
  return `${format(start, "MMM d")} - ${format(end, "MMM d")}`
}

interface AssignableUser {
  id: string
  name: string
  email?: string
  avatarUrl?: string
}

function AssigneeAvatar({ name, avatarUrl, seed }: { name?: string; avatarUrl?: string; seed?: string }) {
  const displayUrl = avatarUrl || generateAvatarDataUrl(seed || name || "unassigned", name || "Unassigned")
  return (
    <img
      src={displayUrl}
      alt={name || "Assignee"}
      className="h-6 w-6 rounded-full border border-slate-700 object-cover bg-slate-900"
      title={name ? `Assigned to ${name}` : "Unassigned"}
    />
  )
}

// Sortable Task Row
function SortableTaskRow({
  task,
  assigneeAvatarUrl,
  onClick,
}: {
  task: Task
  assigneeAvatarUrl?: string
  onClick: () => void
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: task.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      className="flex items-center gap-3 p-3 bg-slate-800/50 border border-slate-700/50 rounded-lg hover:border-slate-600 cursor-pointer"
      onClick={onClick}
    >
      <div
        {...attributes}
        {...listeners}
        className="shrink-0 h-8 w-6 rounded border border-slate-700/70 bg-slate-900/70 flex items-center justify-center cursor-grab active:cursor-grabbing text-slate-400 hover:text-slate-200"
        aria-label="Drag task"
        title="Drag task"
      >
        <GripVertical className="w-4 h-4 text-slate-500" />
      </div>
      <span className="text-lg">{typeLabels[task.type]}</span>
      <div className="flex-1 min-w-0">
        <p className="text-sm font-medium text-slate-200 truncate">{task.title}</p>
      </div>
      <Badge className={`${priorityColors[task.priority]} text-white text-xs`}>
        {task.priority}
      </Badge>
      {task.comments && task.comments.length > 0 && (
        <span className="text-xs text-slate-500">💬 {task.comments.length}</span>
      )}
      <AssigneeAvatar name={task.assigneeName} avatarUrl={assigneeAvatarUrl} seed={task.assigneeId} />
    </div>
  )
}

// Drag Overlay Item
function DragOverlayItem({ task, assigneeAvatarUrl }: { task: Task; assigneeAvatarUrl?: string }) {
  return (
    <div className="flex items-center gap-3 p-3 bg-slate-800 border border-slate-600 rounded-lg shadow-xl rotate-1">
      <GripVertical className="w-4 h-4 text-slate-500" />
      <span className="text-lg">{typeLabels[task.type]}</span>
      <div className="flex-1 min-w-0">
        <p className="text-sm font-medium text-slate-200 truncate">{task.title}</p>
      </div>
      <Badge className={`${priorityColors[task.priority]} text-white text-xs`}>
        {task.priority}
      </Badge>
      <AssigneeAvatar name={task.assigneeName} avatarUrl={assigneeAvatarUrl} seed={task.assigneeId} />
    </div>
  )
}

function SectionDropZone({ id, children }: { id: string; children: ReactNode }) {
  const { isOver, setNodeRef } = useDroppable({ id })

  return (
    <div
      ref={setNodeRef}
      className={`rounded-lg transition-colors ${isOver ? "ring-1 ring-blue-500/60 bg-blue-500/5" : ""}`}
    >
      {children}
    </div>
  )
}

// Collapsible Section
function TaskSection({
  title,
  tasks,
  isOpen,
  onToggle,
  onTaskClick,
  resolveAssigneeAvatar,
  sprintInfo,
}: {
  title: string
  tasks: Task[]
  isOpen: boolean
  onToggle: () => void
  onTaskClick: (task: Task) => void
  resolveAssigneeAvatar: (task: Task) => string | undefined
  sprintInfo?: { name: string; date: string; status: string }
}) {
  return (
    <div className="border border-slate-800 rounded-lg overflow-hidden">
      <button
        onClick={onToggle}
        className="w-full flex items-center justify-between p-4 bg-slate-900 hover:bg-slate-800/50 transition-colors"
      >
        <div className="flex items-center gap-3">
          {isOpen ? (
            <ChevronDown className="w-5 h-5 text-slate-400" />
          ) : (
            <ChevronRight className="w-5 h-5 text-slate-400" />
          )}
          <h3 className="font-medium text-slate-200">{title}</h3>
          <Badge variant="secondary" className="bg-slate-800 text-slate-400">
            {tasks.length}
          </Badge>
        </div>
        {sprintInfo && (
          <div className="flex items-center gap-2 text-sm text-slate-500">
            <Calendar className="w-4 h-4" />
            <span>{sprintInfo.date}</span>
            <Badge variant="outline" className="text-xs">
              {sprintInfo.status}
            </Badge>
          </div>
        )}
      </button>
      
      {isOpen && (
        <div className="p-4 bg-slate-950/50">
          <SortableContext
            items={tasks.map((t) => t.id)}
            strategy={verticalListSortingStrategy}
          >
            <div className="space-y-2">
              {tasks.length === 0 ? (
                <p className="text-sm text-slate-600 text-center py-4">No tasks</p>
              ) : (
                tasks.map((task) => (
                  <SortableTaskRow
                    key={task.id}
                    task={task}
                    assigneeAvatarUrl={resolveAssigneeAvatar(task)}
                    onClick={() => onTaskClick(task)}
                  />
                ))
              )}
            </div>
          </SortableContext>
        </div>
      )}
    </div>
  )
}

interface BacklogViewProps {
  searchQuery?: string
}

export function BacklogView({ searchQuery = "" }: BacklogViewProps) {
  const router = useRouter()
  const [assignableUsers, setAssignableUsers] = useState<AssignableUser[]>([])
  const {
    tasks,
    sprints,
    selectedProjectId,
    updateTask,
    addSprint,
  } = useTaskStore()

  useEffect(() => {
    let active = true
    const loadUsers = async () => {
      try {
        const response = await fetch("/api/auth/users", { cache: "no-store" })
        if (!response.ok) return
        const data = await response.json()
        if (!active || !Array.isArray(data?.users)) return
        setAssignableUsers(
          data.users.map((entry: { id: string; name: string; email?: string; avatarUrl?: string }) => ({
            id: entry.id,
            name: entry.name,
            email: entry.email,
            avatarUrl: entry.avatarUrl,
          })),
        )
      } catch {
        // Keep backlog usable if users lookup fails.
      }
    }
    void loadUsers()
    return () => {
      active = false
    }
  }, [])

  const resolveAssigneeAvatar = (task: Task) => {
    if (!task.assigneeId) return task.assigneeAvatarUrl
    return assignableUsers.find((user) => user.id === task.assigneeId)?.avatarUrl || task.assigneeAvatarUrl
  }

  // Filter tasks by search query
  const matchesSearch = (task: Task): boolean => {
    if (!searchQuery.trim()) return true
    const query = searchQuery.toLowerCase()
    const matchesTitle = task.title.toLowerCase().includes(query)
    const matchesDescription = task.description?.toLowerCase().includes(query) ?? false
    return matchesTitle || matchesDescription
  }

  const [activeId, setActiveId] = useState<string | null>(null)
  const [openSections, setOpenSections] = useState<Record<string, boolean>>({
    current: true,
    backlog: true,
  })
  const [isCreatingSprint, setIsCreatingSprint] = useState(false)
  const [newSprint, setNewSprint] = useState({
    name: "",
    goal: "",
    startDate: "",
    endDate: "",
  })

  // Sensors for drag detection
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    })
  )

  // Get current active sprint
  const now = new Date()
  const currentSprint = sprints.find(
    (s) =>
      s.status === "active" &&
      new Date(s.startDate) <= now &&
      new Date(s.endDate) >= now
  )

  // Get other sprints (not current)
  const otherSprints = sprints.filter((s) => s.id !== currentSprint?.id)

  // Get tasks by section
  const currentSprintTasks = currentSprint
    ? tasks.filter((t) => t.sprintId === currentSprint.id && matchesSearch(t))
    : []

  const backlogTasks = tasks.filter((t) => !t.sprintId && matchesSearch(t))

  // Get active task for drag overlay
  const activeTask = activeId ? tasks.find((t) => t.id === activeId) : null

  const handleDragStart = (event: DragStartEvent) => {
    setActiveId(event.active.id as string)
  }

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event
    setActiveId(null)

    if (!over) return

    const taskId = active.id as string
    const overId = over.id as string
    const overTask = tasks.find((t) => t.id === overId)

    const destinationId = overTask
      ? overTask.sprintId
        ? currentSprint && overTask.sprintId === currentSprint.id
          ? "current"
          : `sprint-${overTask.sprintId}`
        : "backlog"
      : overId

    // If dropped over a section header, move task to that section's sprint
    if (destinationId === "backlog") {
      updateTask(taskId, { sprintId: undefined, status: "open" })
    } else if (destinationId === "current" && currentSprint) {
      updateTask(taskId, { sprintId: currentSprint.id, status: "open" })
    } else if (destinationId.startsWith("sprint-")) {
      const sprintId = destinationId.replace("sprint-", "")
      updateTask(taskId, { sprintId, status: "open" })
    }
  }

  const toggleSection = (section: string) => {
    setOpenSections((prev) => ({ ...prev, [section]: !prev[section] }))
  }

  const handleCreateSprint = () => {
    if (!newSprint.name) return

    addSprint({
      name: newSprint.name,
      goal: newSprint.goal,
      startDate: newSprint.startDate || new Date().toISOString(),
      endDate: newSprint.endDate || new Date().toISOString(),
      status: "planning",
      projectId: selectedProjectId || "2",
    })

    setIsCreatingSprint(false)
    setNewSprint({ name: "", goal: "", startDate: "", endDate: "" })
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCorners}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      <div className="space-y-4">
        {/* Current Sprint Section */}
        <SectionDropZone id="current">
          <TaskSection
            title={currentSprint?.name || "Current Sprint"}
            tasks={currentSprintTasks}
            isOpen={openSections.current}
            onToggle={() => toggleSection("current")}
            onTaskClick={(task) => router.push(`/tasks/${encodeURIComponent(task.id)}`)}
            resolveAssigneeAvatar={resolveAssigneeAvatar}
            sprintInfo={
              currentSprint
                ? {
                    name: currentSprint.name,
                    date: formatSprintDateRange(currentSprint.startDate, currentSprint.endDate),
                    status: currentSprint.status,
                  }
                : undefined
            }
          />
        </SectionDropZone>

        {/* Other Sprints Sections - ordered by start date */}
        {otherSprints
          .sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime())
          .map((sprint) => {
            const sprintTasks = tasks.filter((t) => t.sprintId === sprint.id && matchesSearch(t))
            console.log(`Sprint ${sprint.name}: ${sprintTasks.length} tasks`, sprintTasks.map(t => t.title))
            return (
              <SectionDropZone key={sprint.id} id={`sprint-${sprint.id}`}>
                <TaskSection
                  title={sprint.name}
                  tasks={sprintTasks}
                  isOpen={openSections[sprint.id] ?? false}
                  onToggle={() => toggleSection(sprint.id)}
                  onTaskClick={(task) => router.push(`/tasks/${encodeURIComponent(task.id)}`)}
                  resolveAssigneeAvatar={resolveAssigneeAvatar}
                  sprintInfo={{
                    name: sprint.name,
                    date: formatSprintDateRange(sprint.startDate, sprint.endDate),
                    status: sprint.status,
                  }}
                />
              </SectionDropZone>
            )
          })}

        {/* Create Sprint Button */}
        {!isCreatingSprint ? (
          <Button
            variant="outline"
            className="w-full border-dashed border-slate-700 text-slate-400 hover:text-white hover:border-slate-500"
            onClick={() => setIsCreatingSprint(true)}
          >
            <Plus className="w-4 h-4 mr-2" />
            Create Sprint
          </Button>
        ) : (
          <Card className="bg-slate-900 border-slate-800">
            <CardContent className="p-4 space-y-3">
              <h4 className="font-medium text-slate-200">Create New Sprint</h4>
              <input
                type="text"
                placeholder="Sprint name"
                value={newSprint.name}
                onChange={(e) => setNewSprint({ ...newSprint, name: e.target.value })}
                className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded text-sm text-white"
              />
              <textarea
                placeholder="Sprint goal (optional)"
                value={newSprint.goal}
                onChange={(e) => setNewSprint({ ...newSprint, goal: e.target.value })}
                rows={2}
                className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded text-sm text-white"
              />
              <div className="grid grid-cols-2 gap-3">
                <input
                  type="date"
                  value={newSprint.startDate}
                  onChange={(e) => setNewSprint({ ...newSprint, startDate: e.target.value })}
                  className="px-3 py-2 bg-slate-800 border border-slate-700 rounded text-sm text-white"
                />
                <input
                  type="date"
                  value={newSprint.endDate}
                  onChange={(e) => setNewSprint({ ...newSprint, endDate: e.target.value })}
                  className="px-3 py-2 bg-slate-800 border border-slate-700 rounded text-sm text-white"
                />
              </div>
              <div className="flex gap-2">
                <Button onClick={handleCreateSprint} className="flex-1">
                  Create
                </Button>
                <Button variant="ghost" onClick={() => setIsCreatingSprint(false)}>
                  Cancel
                </Button>
              </div>
            </CardContent>
          </Card>
        )}

        {/* Backlog Section */}
        <SectionDropZone id="backlog">
          <TaskSection
            title="Backlog"
            tasks={backlogTasks}
            isOpen={openSections.backlog}
            onToggle={() => toggleSection("backlog")}
            onTaskClick={(task) => router.push(`/tasks/${encodeURIComponent(task.id)}`)}
            resolveAssigneeAvatar={resolveAssigneeAvatar}
          />
        </SectionDropZone>
      </div>

      <DragOverlay>
        {activeTask ? <DragOverlayItem task={activeTask} assigneeAvatarUrl={resolveAssigneeAvatar(activeTask)} /> : null}
      </DragOverlay>
    </DndContext>
  )
}
