"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { ArrowLeft, Calendar, CheckCircle2, Clock, Pencil, Plus, Trash2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { useTaskStore, SprintStatus } from "@/stores/useTaskStore"
import { parseSprintEnd, parseSprintStart, toLocalDateInputValue } from "@/lib/utils"
import { toast } from "sonner"

type SprintDraft = {
  id?: string
  name: string
  goal: string
  startDate: string
  endDate: string
}

const STATUS_LABELS: Record<SprintStatus, string> = {
  planning: "Planning",
  active: "Active",
  completed: "Completed",
}

const STATUS_BADGE_CLASSES: Record<SprintStatus, string> = {
  planning: "bg-amber-500/10 text-amber-300 border-amber-500/30",
  active: "bg-emerald-500/10 text-emerald-300 border-emerald-500/30",
  completed: "bg-slate-500/10 text-slate-300 border-slate-500/30",
}

function formatDateRange(startDate: string, endDate: string): string {
  const start = parseSprintStart(startDate)
  const end = parseSprintEnd(endDate)
  if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) {
    return "Invalid date range"
  }
  return `${start.toLocaleDateString()} - ${end.toLocaleDateString()}`
}

function buildDefaultDraft(): SprintDraft {
  const startDate = toLocalDateInputValue()
  const endDate = toLocalDateInputValue()
  return {
    name: "",
    goal: "",
    startDate,
    endDate,
  }
}

function toApiError(payload: unknown, fallback: string): string {
  if (!payload || typeof payload !== "object") return fallback
  const candidate = payload as { error?: unknown }
  return typeof candidate.error === "string" && candidate.error.trim().length > 0
    ? candidate.error
    : fallback
}

export default function SprintsPage() {
  const router = useRouter()
  const {
    tasks,
    sprints,
    syncFromServer,
    syncError,
  } = useTaskStore()

  const [authReady, setAuthReady] = useState(false)
  const [isLoading, setIsLoading] = useState(true)
  const [isSaving, setIsSaving] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  const [editorOpen, setEditorOpen] = useState(false)
  const [draft, setDraft] = useState<SprintDraft>(buildDefaultDraft())
  const [editorMode, setEditorMode] = useState<"create" | "edit">("create")

  const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null)

  useEffect(() => {
    let isMounted = true
    const loadSession = async () => {
      try {
        const res = await fetch("/api/auth/session", { cache: "no-store" })
        if (!res.ok) {
          if (isMounted) router.replace("/login")
          return
        }
        if (isMounted) setAuthReady(true)
      } catch {
        if (isMounted) router.replace("/login")
      }
    }

    void loadSession()
    return () => {
      isMounted = false
    }
  }, [router])

  useEffect(() => {
    if (!authReady) return

    const loadData = async () => {
      setIsLoading(true)
      await syncFromServer({ scope: "all" })
      setIsLoading(false)
    }

    void loadData()
  }, [authReady, syncFromServer])

  const sprintTaskCounts = useMemo(() => {
    const counts = new Map<string, { total: number; done: number }>()
    sprints.forEach((sprint) => counts.set(sprint.id, { total: 0, done: 0 }))

    tasks.forEach((task) => {
      if (!task.sprintId) return
      const existing = counts.get(task.sprintId) || { total: 0, done: 0 }
      existing.total += 1
      if (task.status === "done" || task.status === "archived") {
        existing.done += 1
      }
      counts.set(task.sprintId, existing)
    })

    return counts
  }, [sprints, tasks])

  const sortedSprints = useMemo(() => {
    return [...sprints].sort((a, b) => {
      const dateDelta = parseSprintStart(b.startDate).getTime() - parseSprintStart(a.startDate).getTime()
      if (dateDelta !== 0) return dateDelta
      return a.name.localeCompare(b.name)
    })
  }, [sprints])

  const openCreateDialog = () => {
    setEditorMode("create")
    setDraft(buildDefaultDraft())
    setEditorOpen(true)
  }

  const openEditDialog = (sprint: (typeof sprints)[number]) => {
    setEditorMode("edit")
    setDraft({
      id: sprint.id,
      name: sprint.name,
      goal: sprint.goal || "",
      startDate: sprint.startDate,
      endDate: sprint.endDate,
    })
    setEditorOpen(true)
  }

  const validateDraft = (): string | null => {
    if (!draft.name.trim()) return "Sprint name is required"
    if (!draft.startDate) return "Start date is required"
    if (!draft.endDate) return "End date is required"

    const start = parseSprintStart(draft.startDate)
    const end = parseSprintEnd(draft.endDate)
    if (start.getTime() > end.getTime()) {
      return "End date must be on or after start date"
    }

    return null
  }

  const handleSave = async () => {
    const validationError = validateDraft()
    if (validationError) {
      toast.error(validationError)
      return
    }

    setIsSaving(true)
    try {
      const method = editorMode === "create" ? "POST" : "PATCH"
      const payload: Record<string, unknown> = {
        name: draft.name.trim(),
        goal: draft.goal.trim() || undefined,
        startDate: draft.startDate,
        endDate: draft.endDate,
      }

      if (editorMode === "edit") {
        payload.id = draft.id
      }

      const response = await fetch("/api/sprints", {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      })
      const responsePayload = await response.json().catch(() => null)

      if (!response.ok) {
        throw new Error(toApiError(responsePayload, `${method} /api/sprints failed`))
      }

      await syncFromServer({ scope: "all" })
      setEditorOpen(false)
      toast.success(editorMode === "create" ? "Sprint created" : "Sprint updated")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Failed to save sprint"
      toast.error(message)
    } finally {
      setIsSaving(false)
    }
  }

  const handleDelete = async (sprintId: string) => {
    setIsDeleting(true)
    try {
      const response = await fetch("/api/sprints", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: sprintId }),
      })
      const responsePayload = await response.json().catch(() => null)

      if (!response.ok) {
        throw new Error(toApiError(responsePayload, "DELETE /api/sprints failed"))
      }

      await syncFromServer({ scope: "all" })
      setDeleteConfirmId(null)
      toast.success("Sprint deleted")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Failed to delete sprint"
      toast.error(message)
    } finally {
      setIsDeleting(false)
    }
  }

  const openSprintDetails = (sprintId: string) => {
    router.push(`/sprints/${encodeURIComponent(sprintId)}`)
  }

  if (!authReady) {
    return (
      <div className="min-h-screen bg-slate-950 text-slate-100 flex items-center justify-center">
        <p className="text-sm text-slate-400">Checking session...</p>
      </div>
    )
  }

  return (
    <div className="min-h-screen bg-slate-950 text-slate-100">
      <header className="border-b border-slate-800 bg-slate-900/50 backdrop-blur">
        <div className="max-w-[1800px] mx-auto px-4 py-4">
          <div className="flex items-center justify-between gap-4">
            <div className="flex items-center gap-4">
              <Button
                variant="outline"
                className="border-slate-700 text-slate-200 hover:bg-slate-800"
                onClick={() => router.push("/")}
              >
                <ArrowLeft className="w-4 h-4 mr-2" />
                Back to Board
              </Button>
              <div>
                <h1 className="text-xl md:text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
                  Sprints
                </h1>
                <p className="text-xs md:text-sm text-slate-400 mt-1">
                  View and manage sprint plans
                </p>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                className="border-slate-700 text-slate-200 hover:bg-slate-800"
                onClick={() => router.push("/sprints/archive")}
              >
                <Clock className="w-4 h-4 mr-2" />
                Archive
              </Button>
              <Button onClick={openCreateDialog}>
                <Plus className="w-4 h-4 mr-2" />
                New Sprint
              </Button>
            </div>
          </div>
        </div>
      </header>

      <div className="max-w-[1800px] mx-auto px-4 py-6 space-y-4">
        {syncError && (
          <div className="rounded-lg border border-red-500/30 bg-red-500/10 text-red-200 text-sm px-3 py-2">
            Sync error: {syncError}
          </div>
        )}

        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
          <Card className="bg-slate-900 border-slate-800">
            <CardContent className="p-4">
              <p className="text-sm text-slate-400">Total Sprints</p>
              <p className="text-2xl font-semibold text-white mt-1">{sprints.length}</p>
            </CardContent>
          </Card>
          <Card className="bg-slate-900 border-slate-800">
            <CardContent className="p-4">
              <p className="text-sm text-slate-400">Active</p>
              <p className="text-2xl font-semibold text-emerald-300 mt-1">
                {sprints.filter((sprint) => sprint.status === "active").length}
              </p>
            </CardContent>
          </Card>
          <Card className="bg-slate-900 border-slate-800">
            <CardContent className="p-4">
              <p className="text-sm text-slate-400">Planning</p>
              <p className="text-2xl font-semibold text-amber-300 mt-1">
                {sprints.filter((sprint) => sprint.status === "planning").length}
              </p>
            </CardContent>
          </Card>
        </div>

        {isLoading ? (
          <div className="flex items-center justify-center py-12 text-slate-400">
            <span>Loading sprints...</span>
          </div>
        ) : sortedSprints.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-16 text-slate-400">
            <Calendar className="w-14 h-14 mb-4 text-slate-600" />
            <h3 className="text-lg font-medium text-slate-200 mb-2">No Sprints Yet</h3>
            <p className="text-sm mb-4">Create your first sprint to start organizing work cycles.</p>
            <Button onClick={openCreateDialog}>
              <Plus className="w-4 h-4 mr-2" />
              Create Sprint
            </Button>
          </div>
        ) : (
          <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
            {sortedSprints.map((sprint) => {
              const counts = sprintTaskCounts.get(sprint.id) || { total: 0, done: 0 }
              const completion = counts.total > 0 ? Math.round((counts.done / counts.total) * 100) : 0

              return (
                <Card
                  key={sprint.id}
                  className="bg-slate-900 border-slate-800 hover:border-slate-600 transition-colors cursor-pointer group"
                  onClick={() => openSprintDetails(sprint.id)}
                >
                  <CardHeader className="pb-3">
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0">
                        <h3 className="font-semibold text-white truncate group-hover:text-blue-400 transition-colors">
                          {sprint.name}
                        </h3>
                      </div>
                      <Badge variant="outline" className={STATUS_BADGE_CLASSES[sprint.status]}>
                        {STATUS_LABELS[sprint.status]}
                      </Badge>
                    </div>
                  </CardHeader>
                  <CardContent className="space-y-4">
                    {sprint.goal && <p className="text-sm text-slate-300 line-clamp-2">{sprint.goal}</p>}

                    <div className="flex items-center gap-2 text-sm text-slate-400">
                      <Calendar className="w-4 h-4" />
                      <span>{formatDateRange(sprint.startDate, sprint.endDate)}</span>
                    </div>

                    <div className="space-y-1">
                      <div className="flex items-center justify-between text-xs text-slate-400">
                        <span>Task completion</span>
                        <span>{counts.done}/{counts.total} ({completion}%)</span>
                      </div>
                      <div className="h-2 bg-slate-800 rounded-full overflow-hidden">
                        <div
                          className="h-full bg-blue-500 transition-all"
                          style={{ width: `${completion}%` }}
                        />
                      </div>
                    </div>

                    <div className="flex items-center gap-2 pt-1">
                      <Button
                        size="sm"
                        variant="outline"
                        className="border-slate-700 text-slate-200 hover:bg-slate-800"
                        onClick={(event) => {
                          event.stopPropagation()
                          openSprintDetails(sprint.id)
                        }}
                      >
                        <CheckCircle2 className="w-3.5 h-3.5 mr-1.5" />
                        Open
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        className="border-slate-700 text-slate-200 hover:bg-slate-800"
                        onClick={(event) => {
                          event.stopPropagation()
                          openEditDialog(sprint)
                        }}
                      >
                        <Pencil className="w-3.5 h-3.5 mr-1.5" />
                        Edit
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        className="border-red-500/40 text-red-300 hover:bg-red-500/10"
                        onClick={(event) => {
                          event.stopPropagation()
                          setDeleteConfirmId(sprint.id)
                        }}
                      >
                        <Trash2 className="w-3.5 h-3.5 mr-1.5" />
                        Delete
                      </Button>
                    </div>
                  </CardContent>
                </Card>
              )
            })}
          </div>
        )}
      </div>

      <Dialog open={editorOpen} onOpenChange={setEditorOpen}>
        <DialogContent className="bg-slate-900 border-slate-800 text-white w-[95vw] max-w-lg max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editorMode === "create" ? "Create Sprint" : "Edit Sprint"}</DialogTitle>
          </DialogHeader>

          <div className="space-y-4 py-2">
            <div>
              <label className="text-sm text-slate-400">Sprint Name *</label>
              <Input
                value={draft.name}
                onChange={(event) => setDraft((prev) => ({ ...prev, name: event.target.value }))}
                className="mt-1 bg-slate-800 border-slate-700 text-white"
                placeholder="e.g., Sprint 5 - QA Hardening"
              />
            </div>

            <div>
              <label className="text-sm text-slate-400">Goal</label>
              <Textarea
                value={draft.goal}
                onChange={(event) => setDraft((prev) => ({ ...prev, goal: event.target.value }))}
                className="mt-1 bg-slate-800 border-slate-700 text-white"
                rows={3}
                placeholder="What should this sprint deliver?"
              />
            </div>

            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="text-sm text-slate-400">Start Date *</label>
                <Input
                  type="date"
                  value={draft.startDate}
                  onChange={(event) => {
                    const startDate = event.target.value
                    setDraft((prev) => ({
                      ...prev,
                      startDate,
                    }))
                  }}
                  className="mt-1 bg-slate-800 border-slate-700 text-white"
                />
              </div>
              <div>
                <label className="text-sm text-slate-400">End Date *</label>
                <Input
                  type="date"
                  value={draft.endDate}
                  onChange={(event) => {
                    const endDate = event.target.value
                    setDraft((prev) => ({
                      ...prev,
                      endDate,
                    }))
                  }}
                  className="mt-1 bg-slate-800 border-slate-700 text-white"
                />
              </div>
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <Button
                variant="outline"
                className="border-slate-700 text-slate-200 hover:bg-slate-800"
                onClick={() => setEditorOpen(false)}
                disabled={isSaving}
              >
                Cancel
              </Button>
              <Button onClick={handleSave} disabled={isSaving}>
                {isSaving ? "Saving..." : editorMode === "create" ? "Create Sprint" : "Save Changes"}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <Dialog open={deleteConfirmId !== null} onOpenChange={(open) => !open && setDeleteConfirmId(null)}>
        <DialogContent className="bg-slate-900 border-slate-800 text-white w-[95vw] max-w-md">
          <DialogHeader>
            <DialogTitle>Delete Sprint?</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-slate-300">
            This will remove the sprint and keep tasks in the backlog (their sprint assignment will be cleared).
          </p>
          <div className="flex justify-end gap-2 pt-2">
            <Button
              variant="outline"
              className="border-slate-700 text-slate-200 hover:bg-slate-800"
              onClick={() => setDeleteConfirmId(null)}
              disabled={isDeleting}
            >
              Cancel
            </Button>
            <Button
              variant="destructive"
              onClick={() => deleteConfirmId && handleDelete(deleteConfirmId)}
              disabled={isDeleting}
            >
              {isDeleting ? "Deleting..." : "Delete Sprint"}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  )
}
