import { Button } from "@minmon/ui/components/button";
import { statusBadgeVariants } from "@minmon/ui/components/status-badge";
import { cn } from "@minmon/ui/lib/utils";
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/domains")({
  component: RouteComponent,
});

function dnsStatusVariant(status: "MATCH" | "MISMATCH" | "UNRESOLVED") {
  if (status === "MATCH") return "success" as const;
  if (status === "MISMATCH") return "warning" as const;
  return "destructive" as const;
}

function RouteComponent() {
  const domains = useQuery(trpc.domains.list.queryOptions());
  const services = useQuery(trpc.services.list.queryOptions());
  const removeDomain = useMutation({
    mutationFn: async (id: string) => trpcClient.domains.delete.mutate({ id }),
    onSuccess: async () => {
      toast.success("Domain deleted");
      await queryClient.invalidateQueries();
    },
    onError: (error) => toast.error(error.message),
  });
  const checkDns = useMutation({
    mutationFn: async (id: string) => trpcClient.domains.check.mutate({ id }),
    onSuccess: async () => {
      toast.success("DNS check completed");
      await queryClient.invalidateQueries();
    },
    onError: (error) => toast.error(error.message),
  });

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

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

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

  return (
    <PageSection
      title="Domains"
      description="Manage service domains, expected IPs, and DNS resolution checks."
      action={
        <Link to="/dashboard/domains/new">
          <Button>Add domain</Button>
        </Link>
      }
    >
      <ResourceListCard
        title="Domain list"
        description="Use the Check DNS action to resolve A records and compare them with the expected server IP."
        columns={[
          {
            key: "name",
            header: "Domain",
            render: (item: (typeof domains.data)[number]) => (
              <div className="grid gap-1">
                <Link to="/dashboard/domains/$domainId" params={{ domainId: item.id }} className="font-medium hover:underline">
                  {item.name}
                </Link>
                <span className="text-xs text-muted-foreground">{item.remarks || "No remarks"}</span>
              </div>
            ),
          },
          {
            key: "service",
            header: "Service",
            render: (item: (typeof domains.data)[number]) => serviceMap.get(item.serviceId) || item.serviceId,
          },
          {
            key: "expectedServerIp",
            header: "Expected IP",
            render: (item: (typeof domains.data)[number]) => item.expectedServerIp,
          },
          {
            key: "lastResolvedIp",
            header: "Last resolved IP",
            render: (item: (typeof domains.data)[number]) => item.lastResolvedIp || "-",
          },
          {
            key: "status",
            header: "DNS status",
            className: "w-36",
            render: (item: (typeof domains.data)[number]) => (
              <button
                type="button"
                disabled={checkDns.isPending}
                className={cn(
                  statusBadgeVariants({ variant: dnsStatusVariant(item.resolutionStatus) }),
                  "cursor-pointer transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-60",
                )}
                onClick={() => checkDns.mutate(item.id)}
              >
                {item.resolutionStatus}
              </button>
            ),
          },
          {
            key: "actions",
            header: "Actions",
            className: "w-16",
            render: (item: (typeof domains.data)[number]) => (
              <ConfirmDeleteIconButton
                itemLabel={`domain ${item.name}`}
                disabled={removeDomain.isPending}
                onConfirm={() => removeDomain.mutate(item.id)}
              />
            ),
          },
        ]}
        items={domains.data}
        emptyTitle="No domains added"
        emptyDescription="Create a domain after adding a service."
      />
    </PageSection>
  );
}
