import { Button } from "@minmon/ui/components/button";
import { StatusBadge } from "@minmon/ui/components/status-badge";
import { useMutation, useQuery } from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import { toast } from "sonner";

import { ConfirmDeleteIconButton, PageSection, QueryStateCard, ResourceListCard } from "@/components/dashboard-ui";
import { queryClient, trpc, trpcClient } from "@/utils/trpc";

export const Route = createFileRoute("/dashboard/services")({
  component: RouteComponent,
});

function serviceStatusVariant(status: "active" | "down" | "maintenance") {
  if (status === "active") return "success" as const;
  if (status === "down") return "destructive" as const;
  return "warning" as const;
}

function RouteComponent() {
  const services = useQuery(trpc.services.list.queryOptions());
  const servers = useQuery(trpc.servers.list.queryOptions());
  const removeService = useMutation({
    mutationFn: async (id: string) => trpcClient.services.delete.mutate({ id }),
    onSuccess: async () => {
      toast.success("Service deleted");
      await queryClient.invalidateQueries();
    },
    onError: (error) => toast.error(error.message),
  });

  if (services.isLoading || servers.isLoading) {
    return <QueryStateCard title="Loading services" description="Fetching service records and server references." />;
  }

  if (services.isError || servers.isError || !services.data || !servers.data) {
    return <QueryStateCard title="Services unavailable" description="The service list could not be loaded." />;
  }

  const serverMap = new Map(servers.data.map((item) => [item.id, item.name]));

  return (
    <PageSection
      title="Services"
      description="Manage services running on each server, including ports, protocol, and current status."
      action={
        <Link to="/dashboard/services/new">
          <Button>Add service</Button>
        </Link>
      }
    >
      <ResourceListCard
        title="Service list"
        description="Each service belongs to exactly one server. Domains are attached to services."
        columns={[
          {
            key: "name",
            header: "Service",
            render: (item: (typeof services.data)[number]) => (
              <div className="grid gap-1">
                <Link
                  to="/dashboard/services/$serviceId"
                  params={{ serviceId: item.id }}
                  className="font-medium hover:underline"
                >
                  {item.name}
                </Link>
                <span className="text-xs text-muted-foreground">{item.description || "No description"}</span>
              </div>
            ),
          },
          {
            key: "server",
            header: "Server",
            render: (item: (typeof services.data)[number]) => serverMap.get(item.serverId) || item.serverId,
          },
          {
            key: "ports",
            header: "Ports",
            render: (item: (typeof services.data)[number]) =>
              `${item.internalPort ?? "-"} / ${item.externalPort ?? "-"}`,
          },
          {
            key: "protocol",
            header: "Protocol",
            render: (item: (typeof services.data)[number]) => item.protocol,
          },
          {
            key: "status",
            header: "Status",
            className: "w-32",
            render: (item: (typeof services.data)[number]) => (
              <StatusBadge variant={serviceStatusVariant(item.status)}>{item.status}</StatusBadge>
            ),
          },
          {
            key: "actions",
            header: "Actions",
            className: "w-16",
            render: (item: (typeof services.data)[number]) => (
              <ConfirmDeleteIconButton
                itemLabel={`service ${item.name}`}
                disabled={removeService.isPending}
                onConfirm={() => removeService.mutate(item.id)}
              />
            ),
          },
        ]}
        items={services.data}
        emptyTitle="No services added"
        emptyDescription="Create a service after adding at least one server."
      />
    </PageSection>
  );
}
