"use client";

import { useState, useRef, useEffect } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Card, CardContent, CardHeader, CardTitle } from "@turbostarter/ui-web/card";
import { Badge } from "@turbostarter/ui-web/badge";
import { Icons } from "@turbostarter/ui-web/icons";
import { Button } from "@turbostarter/ui-web/button";
import { Input } from "@turbostarter/ui-web/input";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@turbostarter/ui-web/dropdown-menu";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@turbostarter/ui-web/alert-dialog";

import { api } from "~/lib/api/client";

import type { SelectDiagram } from "@turbostarter/db/schema";

export type DiagramResponse = Omit<SelectDiagram, "createdAt" | "updatedAt" | "deletedAt"> & {
  createdAt: string | null;
  updatedAt: string | null;
  deletedAt: string | null;
};

export function timeAgo(date: Date): string {
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
  if (seconds < 0) return "just now";
  if (seconds < 60) return "just now";
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months}mo ago`;
  const years = Math.floor(months / 12);
  return `${years}y ago`;
}

const diagramTypeConfig = {
  bpmn: { label: "BPMN", icon: Icons.Workflow, color: "text-blue-500" },
  er: { label: "E-R", icon: Icons.Database, color: "text-violet-500" },
  orgchart: { label: "Org Chart", icon: Icons.UsersRound, color: "text-green-500" },
  architecture: { label: "Architecture", icon: Icons.Server, color: "text-neutral-500" },
  sequence: { label: "Sequence", icon: Icons.ArrowRightLeft, color: "text-amber-500" },
  flowchart: { label: "Flowchart", icon: Icons.GitBranch, color: "text-rose-500" },
} as const;

interface DiagramCardProps {
  diagram: DiagramResponse;
  onClick?: () => void;
}

export function DiagramCard({ diagram, onClick }: DiagramCardProps) {
  const config = diagramTypeConfig[diagram.type];
  const TypeIcon = config.icon;
  const queryClient = useQueryClient();

  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(diagram.title);
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (!isEditing) {
      setEditValue(diagram.title);
    }
  }, [diagram.title, isEditing]);

  useEffect(() => {
    if (isEditing && inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [isEditing]);

  const renameMutation = useMutation({
    mutationFn: async (title: string) => {
      const res = await api.diagrams[":id"].$patch({
        param: { id: diagram.id },
        json: { title },
      });
      if (!res.ok) throw new Error("Failed to rename diagram");
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["diagrams"] });
      queryClient.invalidateQueries({ queryKey: ["diagram", diagram.id] });
      toast.success("Diagram renamed");
    },
    onError: () => {
      setEditValue(diagram.title);
      toast.error("Failed to rename diagram");
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async () => {
      const res = await api.diagrams[":id"].$delete({
        param: { id: diagram.id },
      });
      if (!res.ok) throw new Error("Failed to delete diagram");
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["diagrams"] });
      toast.success("Diagram deleted");
    },
    onError: () => {
      toast.error("Failed to delete diagram");
    },
  });

  const handleSaveRename = () => {
    const trimmed = editValue.trim();
    if (trimmed && trimmed !== diagram.title) {
      renameMutation.mutate(trimmed);
    } else {
      setEditValue(diagram.title);
    }
    setIsEditing(false);
  };

  const handleCancelRename = () => {
    setEditValue(diagram.title);
    setIsEditing(false);
  };

  return (
    <>
      <Card
        className="cursor-pointer transition-colors hover:bg-accent/50"
        role="button"
        tabIndex={0}
        onKeyDown={(e) => {
          if (e.key === "Enter" || e.key === " ") {
            if (!isEditing) {
              e.preventDefault();
              onClick?.();
            }
          }
        }}
        onClick={() => {
          if (!isEditing) onClick?.();
        }}
      >
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          {isEditing ? (
            <Input
              ref={inputRef}
              value={editValue}
              onChange={(e) => setEditValue(e.target.value)}
              onBlur={handleSaveRename}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault();
                  handleSaveRename();
                } else if (e.key === "Escape") {
                  handleCancelRename();
                }
                e.stopPropagation();
              }}
              onClick={(e) => e.stopPropagation()}
              className="h-6 text-sm font-medium px-1"
              maxLength={255}
            />
          ) : (
            <CardTitle
              className="text-sm font-medium truncate flex-1 cursor-pointer hover:text-primary/80 transition-colors"
              onClick={(e) => {
                e.stopPropagation();
                setEditValue(diagram.title);
                setIsEditing(true);
              }}
              title="Click to rename"
            >
              {diagram.title}
            </CardTitle>
          )}
          <div className="flex items-center gap-1 shrink-0 ml-2">
            <TypeIcon className={`h-4 w-4 ${config.color}`} />
            <DropdownMenu>
              <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                <Button variant="ghost" size="icon" className="h-6 w-6">
                  <Icons.MoreHorizontal className="h-3.5 w-3.5" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end" onClick={(e) => e.stopPropagation()}>
                <DropdownMenuItem
                  onClick={(e) => {
                    e.stopPropagation();
                    setEditValue(diagram.title);
                    setIsEditing(true);
                  }}
                >
                  <Icons.Pencil className="mr-2 h-4 w-4" />
                  Rename
                </DropdownMenuItem>
                <DropdownMenuItem
                  className="text-destructive focus:text-destructive"
                  onClick={(e) => {
                    e.stopPropagation();
                    setShowDeleteDialog(true);
                  }}
                >
                  <Icons.Trash2 className="mr-2 h-4 w-4" />
                  Delete
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        </CardHeader>
        <CardContent>
          <div className="flex items-center justify-between">
            <Badge variant="secondary" className="text-xs">
              {config.label}
            </Badge>
            <span className="text-xs text-muted-foreground">
              {diagram.updatedAt
                ? timeAgo(new Date(diagram.updatedAt))
                : "just now"}
            </span>
          </div>
        </CardContent>
      </Card>

      <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete diagram</AlertDialogTitle>
            <AlertDialogDescription>
              This action cannot be undone. The diagram &quot;{diagram.title}&quot; will be permanently deleted.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              onClick={() => deleteMutation.mutate()}
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}

export { diagramTypeConfig };
