"use client";

import { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Plus,
  Sparkles,
  Loader2,
  MoreVertical,
  Trash2,
  GitBranch,
  GitCommit,
  Rocket,
  Terminal,
  CheckCircle2,
  XCircle,
  Clock,
} from "lucide-react";
import Link from "next/link";
import { useParams } from "next/navigation";
import { ProjectCreationModal } from "@/components/project-creation-modal";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { toast } from "sonner";

interface ContextSnapshot {
  lastCommit?: { sha: string; message: string; author?: string; timestamp?: string };
  currentBranch?: string;
  openPRs?: { number: number; title: string }[];
  openIssues?: { number: number; title: string }[];
  lastDeployment?: { status: string; url?: string };
}

interface ProjectWithStats {
  id: string;
  name: string;
  slug: string;
  productName: string;
  productVision?: string;
  workspacePath?: string;
  status?: string;
  createdAt: string | null;
  updatedAt: string | null;
  giteaRepo?: string;
  giteaRepoUrl?: string;
  theiaWorkspaceUrl?: string;
  contextSnapshot?: ContextSnapshot;
  stats: {
    sessions: number;
    costs: number;
  };
}

function timeAgo(dateStr?: string | null): string {
  if (!dateStr) return "—";
  const date = new Date(dateStr);
  if (isNaN(date.getTime())) return "—";
  const diff = (Date.now() - date.getTime()) / 1000;
  if (diff < 60) return "just now";
  if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
  const days = Math.floor(diff / 86400);
  if (days === 1) return "Yesterday";
  if (days < 7) return `${days}d ago`;
  if (days < 30) return `${Math.floor(days / 7)}w ago`;
  return `${Math.floor(days / 30)}mo ago`;
}

function DeployDot({ status }: { status?: string }) {
  if (!status) return null;
  const map: Record<string, string> = {
    finished: "bg-green-500",
    in_progress: "bg-blue-500 animate-pulse",
    queued: "bg-yellow-400",
    failed: "bg-red-500",
  };
  return (
    <span
      className={`inline-block h-2 w-2 rounded-full ${map[status] ?? "bg-gray-400"}`}
      title={status}
    />
  );
}

export default function ProjectsPage() {
  const params = useParams();
  const workspace = params.workspace as string;
  const { data: session, status } = useSession();

  const [projects, setProjects] = useState<ProjectWithStats[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showCreationModal, setShowCreationModal] = useState(false);
  const [projectToDelete, setProjectToDelete] = useState<ProjectWithStats | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);

  const fetchProjects = async () => {
    try {
      setLoading(true);
      const res = await fetch("/api/projects");
      if (!res.ok) {
        const err = await res.json();
        throw new Error(err.error || "Failed to fetch projects");
      }
      const data = await res.json();
      const loaded: ProjectWithStats[] = data.projects || [];
      setProjects(loaded);
      setError(null);

      // Fire-and-forget: prewarm all provisioned IDE workspaces so containers
      // are already running by the time the user clicks "Open IDE"
      const warmUrls = loaded
        .map((p) => p.theiaWorkspaceUrl)
        .filter((u): u is string => Boolean(u));
      if (warmUrls.length > 0) {
        fetch("/api/projects/prewarm", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ urls: warmUrls }),
        }).catch(() => {}); // ignore errors — this is best-effort
      }
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : "Unknown error");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (status === "authenticated") fetchProjects();
    else if (status === "unauthenticated") setLoading(false);
  }, [status]);

  const handleDeleteProject = async () => {
    if (!projectToDelete) return;
    setIsDeleting(true);
    try {
      const res = await fetch("/api/projects/delete", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ projectId: projectToDelete.id }),
      });
      if (res.ok) {
        toast.success("Project deleted");
        setProjectToDelete(null);
        fetchProjects();
      } else {
        const err = await res.json();
        toast.error(err.error || "Failed to delete project");
      }
    } catch {
      toast.error("An error occurred");
    } finally {
      setIsDeleting(false);
    }
  };

  if (status === "loading") {
    return (
      <div className="flex items-center justify-center py-16">
        <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
      </div>
    );
  }

  return (
    <>
      <div className="container mx-auto py-8 px-4 max-w-6xl">
        {/* Header */}
        <div className="flex items-center justify-between mb-8">
          <div>
            <h1 className="text-2xl font-bold">Projects</h1>
            <p className="text-muted-foreground text-sm mt-1">{session?.user?.email}</p>
          </div>
          <Button onClick={() => setShowCreationModal(true)}>
            <Plus className="mr-2 h-4 w-4" />
            New Project
          </Button>
        </div>

        {/* States */}
        {loading && (
          <div className="flex items-center justify-center py-16">
            <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
          </div>
        )}

        {error && (
          <Card className="border-red-500/30 bg-red-500/5">
            <CardContent className="py-6">
              <p className="text-sm text-red-600">Error: {error}</p>
            </CardContent>
          </Card>
        )}

        {/* Projects Grid */}
        {!loading && !error && projects.length > 0 && (
          <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
            {projects.map((project) => {
              const href = `/${workspace}/project/${project.id}/overview`;
              const snap = project.contextSnapshot;
              const deployStatus = snap?.lastDeployment?.status;

              return (
                <div key={project.id} className="relative group">
                  <Link href={href}>
                    <Card className="hover:border-primary/50 hover:shadow-sm transition-all cursor-pointer h-full">
                      <CardHeader className="pb-3">
                        <div className="flex items-start justify-between gap-2">
                          <div className="flex-1 min-w-0">
                            <CardTitle className="text-base truncate">{project.productName}</CardTitle>
                            <CardDescription className="text-xs mt-0.5">
                              {timeAgo(project.updatedAt)}
                            </CardDescription>
                          </div>
                          <div className="flex items-center gap-1.5 shrink-0">
                            <Badge
                              variant={project.status === "active" ? "default" : "secondary"}
                              className="text-[10px] px-1.5 py-0"
                            >
                              {project.status ?? "active"}
                            </Badge>
                            <DropdownMenu>
                              <DropdownMenuTrigger asChild onClick={(e: React.MouseEvent) => e.preventDefault()}>
                                <Button variant="ghost" size="icon" className="h-7 w-7 opacity-0 group-hover:opacity-100 transition-opacity">
                                  <MoreVertical className="h-3.5 w-3.5" />
                                </Button>
                              </DropdownMenuTrigger>
                              <DropdownMenuContent align="end">
                                <DropdownMenuItem
                                  className="text-red-600 focus:text-red-600"
                                  onClick={(e: React.MouseEvent) => {
                                    e.preventDefault();
                                    setProjectToDelete(project);
                                  }}
                                >
                                  <Trash2 className="mr-2 h-4 w-4" />
                                  Delete
                                </DropdownMenuItem>
                              </DropdownMenuContent>
                            </DropdownMenu>
                          </div>
                        </div>
                      </CardHeader>

                      <CardContent className="space-y-3">
                        {/* Vision */}
                        {project.productVision && (
                          <p className="text-xs text-muted-foreground line-clamp-2">
                            {project.productVision}
                          </p>
                        )}

                        {/* Gitea repo + last commit */}
                        {project.giteaRepo && (
                          <div className="rounded-md border bg-muted/20 p-2 space-y-1">
                            <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
                              <GitBranch className="h-3 w-3" />
                              <span className="font-mono truncate">{project.giteaRepo}</span>
                              {snap?.currentBranch && (
                                <span className="text-[10px] px-1.5 py-0 bg-muted rounded-full shrink-0">
                                  {snap.currentBranch}
                                </span>
                              )}
                            </div>
                            {snap?.lastCommit ? (
                              <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
                                <GitCommit className="h-3 w-3 shrink-0" />
                                <span className="font-mono text-[10px]">{snap.lastCommit.sha.slice(0, 7)}</span>
                                <span className="truncate flex-1">{snap.lastCommit.message}</span>
                                <span className="shrink-0">{timeAgo(snap.lastCommit.timestamp)}</span>
                              </div>
                            ) : (
                              <p className="text-[10px] text-muted-foreground">No commits yet</p>
                            )}
                          </div>
                        )}

                        {/* Footer row: deploy + stats + IDE */}
                        <div className="flex items-center justify-between pt-1 border-t">
                          <div className="flex items-center gap-3 text-xs text-muted-foreground">
                            {deployStatus && (
                              <span className="flex items-center gap-1">
                                <DeployDot status={deployStatus} />
                                {deployStatus === "finished" ? "Live" : deployStatus}
                              </span>
                            )}
                            <span>{project.stats.sessions} sessions</span>
                            <span>${project.stats.costs.toFixed(2)}</span>
                          </div>
                          {project.theiaWorkspaceUrl && (
                            <a
                              href={project.theiaWorkspaceUrl}
                              target="_blank"
                              rel="noopener noreferrer"
                              onClick={(e) => e.stopPropagation()}
                              className="flex items-center gap-1 text-[10px] text-primary hover:underline"
                            >
                              <Terminal className="h-3 w-3" />
                              IDE
                            </a>
                          )}
                        </div>
                      </CardContent>
                    </Card>
                  </Link>
                </div>
              );
            })}

            {/* Create card */}
            <Card
              className="hover:border-primary/50 transition-all cursor-pointer border-dashed"
              onClick={() => setShowCreationModal(true)}
            >
              <CardContent className="flex flex-col items-center justify-center h-full min-h-[220px] p-6">
                <div className="rounded-full bg-muted p-4 mb-3">
                  <Plus className="h-6 w-6 text-muted-foreground" />
                </div>
                <h3 className="font-semibold mb-1 text-sm">New Project</h3>
                <p className="text-xs text-muted-foreground text-center">
                  Auto-provisions a Gitea repo and workspace
                </p>
              </CardContent>
            </Card>
          </div>
        )}

        {/* Empty state */}
        {!loading && !error && projects.length === 0 && (
          <Card className="border-dashed">
            <CardContent className="flex flex-col items-center justify-center py-16">
              <div className="rounded-full bg-muted p-6 mb-4">
                <Sparkles className="h-12 w-12 text-muted-foreground" />
              </div>
              <h3 className="text-lg font-semibold mb-2">No projects yet</h3>
              <p className="text-sm text-muted-foreground text-center max-w-md mb-6">
                Create your first project. Vibn will automatically provision a Gitea repo,
                register webhooks, and prepare your IDE workspace.
              </p>
              <Button size="lg" onClick={() => setShowCreationModal(true)}>
                <Plus className="mr-2 h-4 w-4" />
                Create Your First Project
              </Button>
            </CardContent>
          </Card>
        )}
      </div>

      <ProjectCreationModal
        open={showCreationModal}
        onOpenChange={(open) => {
          setShowCreationModal(open);
          if (!open) fetchProjects();
        }}
        workspace={workspace}
      />

      <AlertDialog open={!!projectToDelete} onOpenChange={(open) => !open && setProjectToDelete(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete &quot;{projectToDelete?.productName}&quot;?</AlertDialogTitle>
            <AlertDialogDescription>
              This will remove the project record. Sessions will be preserved but unlinked.
              The Gitea repo will not be deleted automatically.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isDeleting}>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDeleteProject}
              disabled={isDeleting}
              className="bg-red-600 hover:bg-red-700"
            >
              {isDeleting ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <Trash2 className="mr-2 h-4 w-4" />
              )}
              Delete Project
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}
