import { useState } from "react";
import {
  useDatabaseInfo,
  useRoles,
  useDropDatabase,
  useDropRole,
} from "@/hooks/use-management";
import { useAppStore } from "@/stores/app-store";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { CreateDatabaseDialog } from "./CreateDatabaseDialog";
import { CreateRoleDialog } from "./CreateRoleDialog";
import { AlterRoleDialog } from "./AlterRoleDialog";
import { toast } from "sonner";
import {
  Plus,
  Pencil,
  Trash2,
  ChevronDown,
  ChevronRight,
  HardDrive,
  Users,
  Loader2,
} from "lucide-react";
import type { Tab, RoleInfo } from "@/types";

export function AdminPanel() {
  const { activeConnectionId, currentDatabase, readOnlyMap, addTab } = useAppStore();

  if (!activeConnectionId) {
    return (
      <div className="p-4 text-sm text-muted-foreground">
        Connect to a database to manage it.
      </div>
    );
  }

  const isReadOnly = readOnlyMap[activeConnectionId] ?? true;

  return (
    <div className="flex h-full flex-col overflow-y-auto">
      <DatabasesSection
        connectionId={activeConnectionId}
        currentDatabase={currentDatabase}
        isReadOnly={isReadOnly}
      />
      <RolesSection
        connectionId={activeConnectionId}
        isReadOnly={isReadOnly}
        onOpenRoleManager={() => {
          const tab: Tab = {
            id: crypto.randomUUID(),
            type: "roles",
            title: "Roles & Users",
            connectionId: activeConnectionId,
          };
          addTab(tab);
        }}
      />
    </div>
  );
}

function DatabasesSection({
  connectionId,
  currentDatabase,
  isReadOnly,
}: {
  connectionId: string;
  currentDatabase: string | null;
  isReadOnly: boolean;
}) {
  const [expanded, setExpanded] = useState(true);
  const [createOpen, setCreateOpen] = useState(false);
  const { data: databases, isLoading } = useDatabaseInfo(connectionId);
  const dropMutation = useDropDatabase();

  const handleDrop = (name: string) => {
    if (name === currentDatabase) {
      toast.error("Cannot drop the active database");
      return;
    }
    if (!confirm(`Drop database "${name}"? This will terminate all connections and cannot be undone.`)) {
      return;
    }
    dropMutation.mutate(
      { connectionId, name },
      {
        onSuccess: () => toast.success(`Database "${name}" dropped`),
        onError: (err) => toast.error("Failed to drop database", { description: String(err) }),
      }
    );
  };

  return (
    <div className="border-b">
      <div
        className="flex items-center gap-1 px-3 py-2 cursor-pointer select-none hover:bg-accent/50"
        onClick={() => setExpanded(!expanded)}
      >
        {expanded ? (
          <ChevronDown className="h-3.5 w-3.5 text-muted-foreground" />
        ) : (
          <ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
        )}
        <HardDrive className="h-3.5 w-3.5 text-muted-foreground" />
        <span className="text-xs font-semibold flex-1">Databases</span>
        {!isReadOnly && (
          <Button
            variant="ghost"
            size="sm"
            className="h-5 w-5 p-0"
            onClick={(e) => {
              e.stopPropagation();
              setCreateOpen(true);
            }}
            title="Create Database"
          >
            <Plus className="h-3 w-3" />
          </Button>
        )}
      </div>

      {expanded && (
        <div className="pb-1">
          {isLoading && (
            <div className="px-3 py-2 text-xs text-muted-foreground flex items-center gap-1">
              <Loader2 className="h-3 w-3 animate-spin" /> Loading...
            </div>
          )}
          {databases?.map((db) => (
            <div
              key={db.name}
              className={`group flex items-center gap-2 px-6 py-1 text-xs hover:bg-accent/50 ${
                db.name === currentDatabase ? "text-primary" : ""
              }`}
            >
              <span className="truncate flex-1 font-medium">{db.name}</span>
              <span className="text-[10px] text-muted-foreground shrink-0">{db.size}</span>
              {db.name === currentDatabase && (
                <Badge variant="outline" className="text-[9px] px-1 py-0 shrink-0">
                  active
                </Badge>
              )}
              {!isReadOnly && db.name !== currentDatabase && (
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-5 w-5 p-0 opacity-0 group-hover:opacity-100 text-destructive hover:text-destructive shrink-0"
                  onClick={() => handleDrop(db.name)}
                  title="Drop"
                >
                  <Trash2 className="h-3 w-3" />
                </Button>
              )}
            </div>
          ))}
        </div>
      )}

      <CreateDatabaseDialog
        open={createOpen}
        onOpenChange={setCreateOpen}
        connectionId={connectionId}
      />
    </div>
  );
}

function RolesSection({
  connectionId,
  isReadOnly,
  onOpenRoleManager,
}: {
  connectionId: string;
  isReadOnly: boolean;
  onOpenRoleManager: () => void;
}) {
  const [expanded, setExpanded] = useState(true);
  const [createOpen, setCreateOpen] = useState(false);
  const [alterRole, setAlterRole] = useState<RoleInfo | null>(null);
  const { data: roles, isLoading } = useRoles(connectionId);
  const dropMutation = useDropRole();

  const handleDrop = (name: string) => {
    if (!confirm(`Drop role "${name}"? This cannot be undone.`)) return;
    dropMutation.mutate(
      { connectionId, name },
      {
        onSuccess: () => toast.success(`Role "${name}" dropped`),
        onError: (err) => toast.error("Failed to drop role", { description: String(err) }),
      }
    );
  };

  return (
    <div className="border-b">
      <div
        className="flex items-center gap-1 px-3 py-2 cursor-pointer select-none hover:bg-accent/50"
        onClick={() => setExpanded(!expanded)}
      >
        {expanded ? (
          <ChevronDown className="h-3.5 w-3.5 text-muted-foreground" />
        ) : (
          <ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
        )}
        <Users className="h-3.5 w-3.5 text-muted-foreground" />
        <span className="text-xs font-semibold flex-1">Roles</span>
        <div className="flex gap-0.5" onClick={(e) => e.stopPropagation()}>
          <Button
            variant="ghost"
            size="sm"
            className="h-5 px-1 text-[10px]"
            onClick={onOpenRoleManager}
            title="Open Role Manager"
          >
            Manager
          </Button>
          {!isReadOnly && (
            <Button
              variant="ghost"
              size="sm"
              className="h-5 w-5 p-0"
              onClick={() => setCreateOpen(true)}
              title="Create Role"
            >
              <Plus className="h-3 w-3" />
            </Button>
          )}
        </div>
      </div>

      {expanded && (
        <div className="pb-1">
          {isLoading && (
            <div className="px-3 py-2 text-xs text-muted-foreground flex items-center gap-1">
              <Loader2 className="h-3 w-3 animate-spin" /> Loading...
            </div>
          )}
          {roles?.map((role) => (
            <div
              key={role.name}
              className="group flex items-center gap-1.5 px-6 py-1 text-xs hover:bg-accent/50"
            >
              <span className="truncate flex-1 font-medium">{role.name}</span>
              <div className="flex gap-0.5 shrink-0">
                {role.can_login && (
                  <Badge variant="secondary" className="text-[9px] px-1 py-0">
                    LOGIN
                  </Badge>
                )}
                {role.is_superuser && (
                  <Badge variant="default" className="text-[9px] px-1 py-0 bg-amber-600 hover:bg-amber-600">
                    SUPER
                  </Badge>
                )}
              </div>
              <div className="flex gap-0.5 opacity-0 group-hover:opacity-100 shrink-0">
                {!isReadOnly && (
                  <>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="h-5 w-5 p-0"
                      onClick={() => setAlterRole(role)}
                      title="Edit"
                    >
                      <Pencil className="h-3 w-3" />
                    </Button>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="h-5 w-5 p-0 text-destructive hover:text-destructive"
                      onClick={() => handleDrop(role.name)}
                      title="Drop"
                    >
                      <Trash2 className="h-3 w-3" />
                    </Button>
                  </>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      <CreateRoleDialog
        open={createOpen}
        onOpenChange={setCreateOpen}
        connectionId={connectionId}
      />
      <AlterRoleDialog
        open={!!alterRole}
        onOpenChange={(open) => !open && setAlterRole(null)}
        connectionId={connectionId}
        role={alterRole}
      />
    </div>
  );
}
