import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import {
  useConnections,
  useDeleteConnection,
  useConnect,
  useDisconnect,
} from "@/hooks/use-connections";
import { useAppStore } from "@/stores/app-store";
import { toast } from "sonner";
import {
  Database,
  Plug,
  Unplug,
  Pencil,
  Trash2,
  Plus,
  Loader2,
} from "lucide-react";
import type { ConnectionConfig } from "@/types";
import { EnvironmentBadge } from "@/components/connections/EnvironmentBadge";
import { ENVIRONMENTS } from "@/lib/environment";
import { useState } from "react";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onEdit: (conn: ConnectionConfig) => void;
  onNew: () => void;
}

export function ConnectionList({ open, onOpenChange, onEdit, onNew }: Props) {
  const { data: connections } = useConnections();
  const deleteMutation = useDeleteConnection();
  const connectMutation = useConnect();
  const disconnectMutation = useDisconnect();
  const { connectedIds, activeConnectionId } = useAppStore();
  const [connectingId, setConnectingId] = useState<string | null>(null);

  const handleConnect = (conn: ConnectionConfig) => {
    setConnectingId(conn.id);
    connectMutation.mutate(conn, {
      onSuccess: () => {
        toast.success(`Connected to ${conn.name}`);
        onOpenChange(false);
      },
      onError: (err) => {
        toast.error("Connection failed", { description: String(err) });
      },
      onSettled: () => {
        setConnectingId(null);
      },
    });
  };

  const handleDisconnect = (id: string) => {
    disconnectMutation.mutate(id, {
      onSuccess: () => toast.success("Disconnected"),
      onError: (err) =>
        toast.error("Disconnect failed", { description: String(err) }),
    });
  };

  const handleDelete = (id: string) => {
    deleteMutation.mutate(id, {
      onSuccess: () => toast.success("Connection deleted"),
      onError: (err) =>
        toast.error("Delete failed", { description: String(err) }),
    });
  };

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent side="left" className="w-[400px] max-w-[90vw] p-0" showCloseButton={false}>
        <SheetHeader className="px-4 pt-4 pb-2">
          <SheetTitle className="flex items-center justify-between">
            Connections
            <Button size="sm" variant="outline" onClick={onNew}>
              <Plus className="mr-1 h-4 w-4" />
              New
            </Button>
          </SheetTitle>
        </SheetHeader>
        <div className="overflow-y-auto overflow-x-hidden" style={{ height: "calc(100vh - 80px)" }}>
          <div className="space-y-2 px-4 pb-4">
            {(() => {
              if (!connections || connections.length === 0) {
                return (
                  <div className="py-8 text-center text-sm text-muted-foreground">
                    No saved connections.
                    <br />
                    Click "New" to add one.
                  </div>
                );
              }

              const envOrder = ["prod", "stage", "dev", "local"] as const;
              const grouped = new Map<string, ConnectionConfig[]>();
              for (const conn of connections) {
                const key = conn.environment ?? "";
                const list = grouped.get(key);
                if (list) list.push(conn);
                else grouped.set(key, [conn]);
              }
              const sortedKeys = [...grouped.keys()].sort((a, b) => {
                const ai = a ? envOrder.indexOf(a as typeof envOrder[number]) : envOrder.length;
                const bi = b ? envOrder.indexOf(b as typeof envOrder[number]) : envOrder.length;
                return (ai === -1 ? envOrder.length : ai) - (bi === -1 ? envOrder.length : bi);
              });
              const showHeaders = sortedKeys.length > 1;

              return sortedKeys.map((key) => {
                const group = grouped.get(key)!;
                const envDef = ENVIRONMENTS.find((e) => e.value === key);
                return (
                  <div key={key || "__none__"}>
                    {showHeaders && (
                      <div className="mb-1 mt-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase text-muted-foreground first:mt-0">
                        {envDef ? (
                          <>
                            <span className="h-2 w-2 rounded-full" style={{ backgroundColor: envDef.color }} />
                            {envDef.label}
                          </>
                        ) : (
                          "Other"
                        )}
                      </div>
                    )}
                    {group.map((conn) => {
                      const isConnected = connectedIds.has(conn.id);
                      const isActive = activeConnectionId === conn.id;
                      return (
                        <div
                          key={conn.id}
                          className={`flex items-center gap-2 overflow-hidden rounded-md border p-3 mb-2 last:mb-0 ${
                            isActive ? "border-primary bg-accent" : ""
                          }`}
                        >
                          {conn.color ? (
                            <span
                              className="h-4 w-4 shrink-0 rounded-full"
                              style={{ backgroundColor: conn.color }}
                            />
                          ) : (
                            <Database className="h-4 w-4 shrink-0 text-muted-foreground" />
                          )}
                          <div className="min-w-0 flex-1">
                            <div className="flex items-center gap-1.5 truncate text-sm font-medium">
                              {conn.name}
                              <EnvironmentBadge environment={conn.environment} size="sm" />
                            </div>
                            <div className="truncate text-xs text-muted-foreground">
                              {conn.host}:{conn.port}/{conn.database}
                            </div>
                          </div>
                          <div className="flex shrink-0 items-center gap-0.5">
                            {isConnected ? (
                              <Button
                                size="icon"
                                variant="ghost"
                                className="h-7 w-7"
                                onClick={() => handleDisconnect(conn.id)}
                                disabled={disconnectMutation.isPending}
                              >
                                <Unplug className="h-3.5 w-3.5" />
                              </Button>
                            ) : (
                              <Button
                                size="icon"
                                variant="ghost"
                                className="h-7 w-7"
                                onClick={() => handleConnect(conn)}
                                disabled={connectingId !== null}
                              >
                                {connectingId === conn.id ? (
                                  <Loader2 className="h-3.5 w-3.5 animate-spin" />
                                ) : (
                                  <Plug className="h-3.5 w-3.5" />
                                )}
                              </Button>
                            )}
                            <Button
                              size="icon"
                              variant="ghost"
                              className="h-7 w-7"
                              onClick={() => onEdit(conn)}
                            >
                              <Pencil className="h-3.5 w-3.5" />
                            </Button>
                            <Button
                              size="icon"
                              variant="ghost"
                              className="h-7 w-7 text-destructive"
                              onClick={() => handleDelete(conn.id)}
                              disabled={deleteMutation.isPending}
                            >
                              <Trash2 className="h-3.5 w-3.5" />
                            </Button>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                );
              });
            })()}
          </div>
        </div>
      </SheetContent>
    </Sheet>
  );
}
