"use client";

import Breadcrumbs from "@components/Breadcrumbs";
import Button from "@components/Button";
import Card from "@components/Card";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@components/DropdownMenu";
import FullTooltip from "@components/FullTooltip";
import InlineLink from "@components/InlineLink";
import useRedirect from "@hooks/useRedirect";
import useFetchApi from "@utils/api";
import { cn, singularize } from "@utils/helpers";
import {
  ArrowUpRightIcon,
  HelpCircle,
  Layers3Icon,
  MoreVertical,
  PencilLineIcon,
  ServerIcon,
  ShieldCheckIcon,
  ShieldXIcon,
  Trash2,
} from "lucide-react";
import { useRouter, useSearchParams } from "next/navigation";
import { useTranslations } from "next-intl";
import React, { useMemo } from "react";
import useUrlTab from "@/hooks/useUrlTab";
import NetworkRoutesIcon from "@/assets/icons/NetworkRoutesIcon";
import { usePermissions } from "@/contexts/PermissionsProvider";
import { Network, NetworkResource, NetworkRouter } from "@/interfaces/Network";
import PageContainer from "@/layouts/PageContainer";
import { NetworkInformationSquare } from "@/modules/networks/misc/NetworkInformationSquare";
import { NetworkAccessControlProvider } from "@/modules/networks/NetworkAccessControlProvider";
import {
  NetworkProvider,
  useNetworksContext,
} from "@/modules/networks/NetworkProvider";
import { ResourcesTabContent } from "@/modules/networks/resources/ResourcesTabContent";
import { NetworkRoutingPeersTabContent } from "@/modules/networks/routing-peers/NetworkRoutingPeersTabContent";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@components/Tabs";
import PeerIcon from "@/assets/icons/PeerIcon";
import ReverseProxyIcon from "@/assets/icons/ReverseProxyIcon";
import { ReverseProxyFlatTargetsTabContent } from "@/modules/reverse-proxy/targets/flat/ReverseProxyFlatTargetsTabContent";
import ReverseProxiesProvider, {
  flattenReverseProxies,
  useReverseProxies,
} from "@/contexts/ReverseProxiesProvider";
import { SkeletonNetwork } from "@components/skeletons/SkeletonNetwork";

export default function NetworkDetailPage() {
  const queryParameter = useSearchParams();
  const networkId = queryParameter.get("id");
  const { data: network, isLoading } = useFetchApi<Network>(
    `/networks/${networkId}`,
    true,
  );

  useRedirect("/networks", false, !networkId);

  return network && !isLoading ? (
    <ReverseProxiesProvider initialNetwork={network}>
      <NetworkOverview network={network} />
    </ReverseProxiesProvider>
  ) : (
    <SkeletonNetwork />
  );
}

function NetworkOverview({ network }: Readonly<{ network: Network }>) {
  const t = useTranslations("networks");
  const tReverseProxy = useTranslations("reverseProxy");
  const { permission } = usePermissions();

  const { data: resources, isLoading: isResourcesLoading } = useFetchApi<
    NetworkResource[]
  >(`/networks/${network.id}/resources`);
  const { data: routers, isLoading: isRoutersLoading } = useFetchApi<
    NetworkRouter[]
  >(`/networks/${network.id}/routers`);

  const { reverseProxies, isLoading: isServicesLoading } = useReverseProxies();
  const services = useMemo(
    () => flattenReverseProxies({ reverseProxies, network }),
    [reverseProxies, network],
  );

  const [tab, setTab] = useUrlTab(
    ["resources", "routing-peers", "services"],
    "resources",
  );

  const isActive = !!(
    network?.routing_peers_count && network.routing_peers_count > 0
  );

  return (
    <PageContainer>
      <NetworkAccessControlProvider>
        <NetworkProvider network={network}>
          <div className={"p-default py-6"}>
            <Breadcrumbs>
              <Breadcrumbs.Item
                href={"/networks"}
                label={t("title")}
                disabled={!permission.networks.read}
                icon={<NetworkRoutesIcon size={13} />}
              />
              <Breadcrumbs.Item
                href={"/network"}
                label={network.name}
                active={true}
              />
            </Breadcrumbs>

            <div className={"flex justify-between max-w-6xl"}>
              <div
                className={"w-full lg:w-1/2 flex justify-between items-center"}
              >
                <div
                  className={cn(
                    "flex items-center w-full",
                    !network.description && "gap-2",
                  )}
                >
                  <NetworkInformationSquare
                    name={network.name}
                    active={isActive}
                    size={"lg"}
                    description={network.description}
                  />
                </div>
                <NetworkActions />
              </div>
            </div>

            <div className={"flex gap-10 w-full mt-8 max-w-6xl items-start"}>
              <NetworkInformationCard network={network} />
            </div>
          </div>

          <Tabs
            defaultValue={tab}
            onValueChange={setTab}
            value={tab}
            className={"pb-0 mb-0"}
          >
            <TabsList justify={"start"} className={"px-8"}>
              <TabsTrigger value={"resources"} data-testid="network-tab-resources">
                <Layers3Icon size={14} />
                {singularize(t("resources"), network?.resources?.length)}
              </TabsTrigger>
              <TabsTrigger
                value={"routing-peers"}
                data-testid="network-tab-routing-peers"
              >
                <PeerIcon
                  size={12}
                  className={
                    "fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
                  }
                />
                {singularize(t("routingPeers"), network?.routing_peers_count)}
              </TabsTrigger>
              <TabsTrigger value={"services"} data-testid="network-tab-services">
                <ReverseProxyIcon
                  size={16}
                  className={
                    "fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
                  }
                />
                {singularize(tReverseProxy("services"), services.length)}
              </TabsTrigger>
            </TabsList>

            <TabsContent value={"resources"} className={"pb-8"}>
              <ResourcesTabContent
                data={resources}
                isLoading={isResourcesLoading}
              />
            </TabsContent>

            <TabsContent value={"routing-peers"} className={"pb-8"}>
              <NetworkRoutingPeersTabContent
                routers={routers}
                isLoading={isRoutersLoading}
              />
            </TabsContent>

            <TabsContent value={"services"} className={"pb-8"}>
              <ReverseProxyFlatTargetsTabContent
                targets={services}
                isLoading={isServicesLoading}
              />
            </TabsContent>
          </Tabs>
        </NetworkProvider>
      </NetworkAccessControlProvider>
    </PageContainer>
  );
}

function NetworkActions() {
  const { permission } = usePermissions();
  const { deleteNetwork, openEditNetworkModal, network } = useNetworksContext();
  const router = useRouter();

  if (!network) return;

  return (
    <DropdownMenu modal={false}>
      <DropdownMenuTrigger
        asChild={true}
        onClick={(e) => {
          e.stopPropagation();
          e.preventDefault();
        }}
      >
        <Button variant={"secondary"} className={"!px-3"} data-testid="network-detail-actions">
          <MoreVertical size={16} className={"shrink-0"} />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent className="w-auto" align="end">
        <DropdownMenuItem
          onClick={() => openEditNetworkModal(network)}
          disabled={!permission.networks.update}
          data-testid="rename-network"
        >
          <div className={"flex gap-3 items-center"}>
            <PencilLineIcon size={14} className={"shrink-0"} />
            Rename
          </div>
        </DropdownMenuItem>

        <DropdownMenuSeparator />

        <DropdownMenuItem
          onClick={() =>
            deleteNetwork(network).then(() => router.push("/networks"))
          }
          variant={"danger"}
          disabled={!permission.networks.delete}
        >
          <div className={"flex gap-3 items-center"}>
            <Trash2 size={14} className={"shrink-0"} />
            Delete
          </div>
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

function NetworkInformationCard({ network }: Readonly<{ network: Network }>) {
  const t = useTranslations("networks");
  const tCommon = useTranslations("common");
  const isHighlyAvailable = !!(
    network?.routing_peers_count && network?.routing_peers_count >= 2
  );

  const disabledText = useMemo(
    () => (
      <>
        High availability is currently{" "}
        <span className={"text-yellow-400 font-medium"}>
          {tCommon("inactive")}
        </span>{" "}
        for this network.
      </>
    ),
    [tCommon],
  );

  const enabledText = useMemo(
    () => (
      <>
        High availability is{" "}
        <span className={"text-green-500 font-medium"}>
          {tCommon("active")}
        </span>{" "}
        for this network.
      </>
    ),
    [tCommon],
  );

  const policyCount = network.policies?.length ?? 0;

  return (
    <Card className={"w-full lg:w-1/2"}>
      <Card.List>
        <Card.ListItem
          tooltip={false}
          label={
            <>
              <ServerIcon size={16} />
              High Availability
            </>
          }
          value={
            <FullTooltip
              interactive={false}
              content={
                <div className={"max-w-xs text-xs"}>
                  {isHighlyAvailable ? enabledText : disabledText}
                  {isHighlyAvailable ? (
                    <div className={"inline-flex mt-2"}>
                      You can add more routing peers to increase the
                      availability of this network.
                    </div>
                  ) : (
                    <div className={"inline-flex mt-2"}>
                      Go ahead and add more routing peers or groups with routing
                      peers to enable high availability for this network.
                    </div>
                  )}
                </div>
              }
            >
              <div
                className={cn(
                  "flex gap-2.5 items-center text-nb-gray-300 text-sm cursor-help",
                )}
              >
                <span
                  className={cn(
                    "h-2 w-2 rounded-full",
                    !isHighlyAvailable ? "bg-yellow-400" : "bg-green-500",
                  )}
                ></span>
                {isHighlyAvailable ? tCommon("active") : tCommon("inactive")}
                <HelpCircle size={12} />
              </div>
            </FullTooltip>
          }
        />
        <Card.ListItem
          tooltip={false}
          label={
            policyCount > 0 ? (
              <>
                <ShieldCheckIcon size={16} className={"text-green-500"} />
                {t("activePoliciesCount", { count: policyCount })}
              </>
            ) : (
              <>
                <ShieldXIcon size={16} className={"text-red-500"} />
                {t("noActivePolicies")}
              </>
            )
          }
          value={
            policyCount > 0 ? (
              <InlineLink href={"/access-control"}>
                {t("goToPolicies")}
                <ArrowUpRightIcon size={14} />
              </InlineLink>
            ) : null
          }
        />
      </Card.List>
    </Card>
  );
}
