import { useState, type FormEvent } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { client, type LabelResponse } from "@/client";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
import { useToast } from "@/hooks/use-toast";
import { cn } from "@/lib/utils";
import { Pencil, Plus, Trash2, X } from "lucide-react";

const PRESET_COLORS = [
  "#EF4444", "#F97316", "#F59E0B", "#22C55E", "#14B8A6",
  "#3B82F6", "#6366F1", "#A855F7", "#EC4899", "#78716C",
  "#DC2626", "#EA580C", "#D97706", "#16A34A", "#0D9488",
  "#2563EB", "#4F46E5", "#9333EA", "#DB2777", "#57534E",
];

function LabelManageDialog({
  open,
  onOpenChange,
  projectName,
  onSelect,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  projectName: string;
  onSelect?: (label: LabelResponse) => void;
}) {
  const qc = useQueryClient();
  const { toast } = useToast();
  const [showForm, setShowForm] = useState(false);
  const [editId, setEditId] = useState<string | null>(null);

  const queryKey = ["labels", projectName];
  const { data: labels = [] } = useQuery({
    queryKey,
    queryFn: async () => {
      const res = await client.issuesListLabels(projectName);
      return res.data ?? [];
    },
    enabled: open,
    retry: false,
  });

  const invalidate = () => qc.invalidateQueries({ queryKey });

  const createMutation = useMutation({
    mutationFn: async (data: { name: string; color: string; description?: string | null }) => {
      await client.issuesCreateLabel(projectName, data);
    },
    onSuccess: () => { invalidate(); setShowForm(false); },
    onError: (e: any) => toast({ title: "Failed", description: String(e?.message ?? e), variant: "destructive" }),
  });

  const updateMutation = useMutation({
    mutationFn: async ({ id, ...data }: { id: string; name?: string; color?: string; description?: string | null }) => {
      await client.issuesUpdateLabel(projectName, id, data);
    },
    onSuccess: () => { invalidate(); setEditId(null); },
    onError: (e: any) => toast({ title: "Failed", description: String(e?.message ?? e), variant: "destructive" }),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      await client.issuesDeleteLabel(projectName, id);
    },
    onSuccess: () => invalidate(),
    onError: (e: any) => toast({ title: "Failed", description: String(e?.message ?? e), variant: "destructive" }),
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader className="flex flex-row items-center justify-between">
          <DialogTitle>Manage labels</DialogTitle>
          <Button className="h-7 px-2 text-[12px]" variant="ghost" onClick={() => setShowForm(true)}>
            <Plus className="size-3.5" />
          </Button>
        </DialogHeader>

        {showForm && (
          <LabelForm
            onSubmit={(data) => createMutation.mutate(data)}
            onCancel={() => setShowForm(false)}
            submitting={createMutation.isPending}
          />
        )}

        <div className="max-h-[300px] space-y-1 overflow-y-auto">
          {labels.length === 0 && !showForm && (
            <p className="text-center text-[12px] text-muted-foreground py-4">No labels yet</p>
          )}
          {labels.map((label) => (
            <div key={label.id}>
              {editId === label.id ? (
                <LabelForm
                  initialName={label.name}
                  initialColor={label.color}
                  initialDescription={label.description}
                  onSubmit={(data) => updateMutation.mutate({ id: label.id, ...data })}
                  onCancel={() => setEditId(null)}
                  submitting={updateMutation.isPending}
                />
              ) : (
                <div className="flex items-center gap-2 rounded py-1 px-1 hover:bg-muted/50">
                  <span
                    className="h-4 w-4 shrink-0 rounded-full"
                    style={{ backgroundColor: label.color }}
                  />
                  <span className="flex-1 text-[12px] font-heading font-medium text-foreground">
                    {label.name}
                  </span>
                  {onSelect && (
                    <Button className="h-6 px-2 text-[11px]" variant="ghost" onClick={() => { onSelect(label); onOpenChange(false); }}>
                      Select
                    </Button>
                  )}
                  <button className="grid size-6 place-items-center rounded text-muted-foreground hover:text-foreground cursor-pointer" onClick={() => setEditId(label.id)}>
                    <Pencil className="size-3" />
                  </button>
                  <AlertDialog>
                    <AlertDialogTrigger asChild>
                      <button className="grid size-6 place-items-center rounded text-muted-foreground hover:text-destructive cursor-pointer">
                        <Trash2 className="size-3" />
                      </button>
                    </AlertDialogTrigger>
                    <AlertDialogContent>
                      <AlertDialogHeader>
                        <AlertDialogTitle>Delete label &ldquo;{label.name}&rdquo;?</AlertDialogTitle>
                        <AlertDialogDescription>This will remove it from all issues.</AlertDialogDescription>
                      </AlertDialogHeader>
                      <AlertDialogFooter>
                        <AlertDialogCancel>Cancel</AlertDialogCancel>
                        <AlertDialogAction onClick={() => deleteMutation.mutate(label.id)}>Delete</AlertDialogAction>
                      </AlertDialogFooter>
                    </AlertDialogContent>
                  </AlertDialog>
                </div>
              )}
            </div>
          ))}
        </div>
      </DialogContent>
    </Dialog>
  );
}

function LabelForm({
  initialName = "",
  initialColor = "#3B82F6",
  initialDescription = "",
  onSubmit,
  onCancel,
  submitting,
}: {
  initialName?: string;
  initialColor?: string;
  initialDescription?: string | null;
  onSubmit: (data: { name: string; color: string; description?: string | null }) => void;
  onCancel: () => void;
  submitting: boolean;
}) {
  const [color, setColor] = useState(initialColor);

  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    const name = (form.get("name") as string).trim();
    const description = (form.get("description") as string)?.trim() || null;
    if (!name) return;
    onSubmit({ name, color, description });
  };

  return (
    <form className="rounded border border-border p-3 mb-2 space-y-2 bg-muted/20" onSubmit={(e) => void handleSubmit(e)}>
      <div className="flex items-center gap-2">
        <Input className="h-8 text-[12px]" name="name" placeholder="Label name" defaultValue={initialName} required autoFocus />
        <div className="flex items-center gap-0.5">
          {PRESET_COLORS.slice(0, 8).map((c) => (
            <button
              key={c}
              type="button"
              className={cn("h-6 w-6 rounded border-2 cursor-pointer", color === c ? "border-foreground" : "border-transparent")}
              style={{ backgroundColor: c }}
              onClick={() => setColor(c)}
            />
          ))}
        </div>
      </div>
      <Input className="h-8 text-[12px]" name="description" placeholder="Description (optional)" defaultValue={initialDescription ?? ""} />
      <div className="flex items-center gap-2">
        {PRESET_COLORS.slice(8).map((c) => (
          <button
            key={c}
            type="button"
            className={cn("h-6 w-6 rounded border-2 cursor-pointer", color === c ? "border-foreground" : "border-transparent")}
            style={{ backgroundColor: c }}
            onClick={() => setColor(c)}
          />
        ))}
        <div className="flex-1" />
        <Button className="h-7 px-3 text-[11px]" variant="outline" type="button" onClick={onCancel}>
          <X className="size-3" />
        </Button>
        <Button className="h-7 px-3 text-[11px]" disabled={submitting} type="submit">
          {submitting ? "Saving..." : "Save"}
        </Button>
      </div>
    </form>
  );
}

export { LabelManageDialog };
