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 { 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]) => (
              <StatusBadge variant={dnsStatusVariant(item.resolutionStatus)}>{item.resolutionStatus}</StatusBadge>
            ),
          },
          {
            key: "actions",
            header: "Actions",
            className: "w-44",
            render: (item: (typeof domains.data)[number]) => (
              <div className="flex flex-col items-start gap-2">
                <Button
                  type="button"
                  variant="ghost"
                  className="h-auto px-0"
                  disabled={checkDns.isPending}
                  onClick={() => checkDns.mutate(item.id)}
                >
                  Check DNS
                </Button>
                <Button
                  type="button"
                  variant="ghost"
                  className="h-auto px-0 text-red-600 hover:text-red-700"
                  disabled={removeDomain.isPending}
                  onClick={() => {
                    if (confirm(`Delete domain \"${item.name}\"?`)) {
                      removeDomain.mutate(item.id);
                    }
                  }}
                >
                  Delete
                </Button>
              </div>
            ),
          },
        ]}
        items={domains.data}
        emptyTitle="No domains added"
        emptyDescription="Create a domain after adding a service."
      />
    </PageSection>
  );
}
