import { Button } from "@/components/ui/button";
import { SearchInput } from "@/components/ui/search-input";
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import { VisuallyHidden as VisuallyHiddenPrimitive } from "radix-ui";
const VisuallyHidden = VisuallyHiddenPrimitive.Root;
import { FileEdit, Trash2, TriangleAlert, Wrench } from "lucide-react";
import { useState } from "react";
import McpIcon from "../dashboard/SystemConnectivity/nodes/Mcpx_Icon.svg?react";
import { useDomainIcon } from "@/hooks/useDomainIcon";
import type { ToolGroup } from "@/store/access-controls";
import type { TargetServer } from "@mcpx/shared-model";

export const validateToolGroupName = (
  name: string,
): { isValid: boolean; error?: string } => {
  const trimmedName = name.trim();

  if (!trimmedName) {
    return { isValid: false, error: "Tool Group name is required" };
  }

  const allowed = /^[A-Za-z0-9_\s-]+$/;
  if (!allowed.test(trimmedName)) {
    return {
      isValid: false,
      error:
        "Only letters, digits, spaces, dash (-) and underscore (_) are allowed",
    };
  }

  return { isValid: true };
};

interface ToolGroupSheetProps {
  isOpen: boolean;
  onOpenChange: (open: boolean) => void;
  selectedToolGroup: ToolGroup | null;
  toolGroups: ToolGroup[];
  providers: TargetServer[];
  onEditGroup?: (group: ToolGroup) => void;
  onEditToolGroup?: (group: ToolGroup) => void;
  onDeleteGroup?: (group: ToolGroup) => void;
}

function DomainIcon({
  provider,
  size = 16,
}: {
  provider: TargetServer;
  size?: number;
}) {
  const iconSrc = useDomainIcon(provider.name);

  let imageColor = "black";
  if (!iconSrc) {
    imageColor = provider.icon || imageColor;
  }

  return iconSrc ? (
    <img
      src={iconSrc}
      alt="favicon"
      className="object-contain"
      style={{ width: size, height: size }}
    />
  ) : (
    <McpIcon style={{ color: imageColor, width: size, height: size }} />
  );
}

export function ToolGroupSheet({
  isOpen,
  onOpenChange,
  selectedToolGroup,
  toolGroups,
  providers,
  onEditGroup,
  onEditToolGroup,
  onDeleteGroup,
}: ToolGroupSheetProps) {
  const [searchQuery, setSearchQuery] = useState("");

  return (
    <Sheet open={isOpen} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        className="w-[600px] max-w-[600px]! bg-white p-0 flex flex-col [&>button]:hidden gap-0 overflow-x-hidden border-l-2 border-primary"
        style={{
          overflowX: "hidden",
          boxShadow: "-4px 0 60px 0 rgba(0, 0, 0, 0.25)",
        }}
      >
        <VisuallyHidden>
          <SheetTitle>
            {toolGroups.find((g) => g.id === selectedToolGroup?.id)?.name ||
              selectedToolGroup?.name ||
              "Tool Group"}
          </SheetTitle>
        </VisuallyHidden>
        <SheetHeader className="px-6">
          <div className="flex items-center justify-between mt-6 gap-2 min-w-0">
            <div
              className="flex-1 text-xl font-semibold text-gray-900 truncate min-w-0"
              style={{ fontWeight: 600 }}
              title={
                toolGroups.find((g) => g.id === selectedToolGroup?.id)?.name ||
                selectedToolGroup?.name ||
                ""
              }
            >
              {toolGroups.find((g) => g.id === selectedToolGroup?.id)?.name ||
                selectedToolGroup?.name ||
                ""}
            </div>

            <div className="flex items-center gap-1">
              {onEditToolGroup && selectedToolGroup && (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => onEditToolGroup(selectedToolGroup)}
                  className="p-2"
                  title="Edit Tool Group"
                >
                  <FileEdit className="w-4 h-4" />
                </Button>
              )}
              {onEditGroup && selectedToolGroup && (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => onEditGroup(selectedToolGroup)}
                  className="p-2"
                  title="Update Tools"
                >
                  <Wrench className="w-4 h-4" />
                </Button>
              )}
              {onDeleteGroup && selectedToolGroup && (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => onDeleteGroup(selectedToolGroup)}
                  className="p-2"
                  title="Delete"
                >
                  <Trash2 className="w-4 h-4" />
                </Button>
              )}
            </div>
          </div>
          <SheetDescription></SheetDescription>
        </SheetHeader>

        {/* Description */}
        {(() => {
          const actualGroup = toolGroups.find(
            (g) => g.id === selectedToolGroup?.id,
          );
          const description =
            actualGroup?.description || selectedToolGroup?.description;
          if (!description) return null;

          const truncatedDescription =
            description.length > 200
              ? `${description.substring(0, 200)}...`
              : description;

          return (
            <div className="px-6 overflow-hidden">
              <p
                className="text-sm wrap-break-word"
                style={{
                  fontSize: "14px",
                  wordBreak: "break-word",
                  overflowWrap: "break-word",
                  maxWidth: "100%",
                  overflow: "hidden",
                }}
                title={description.length > 200 ? description : undefined}
              >
                {truncatedDescription}
              </p>
            </div>
          );
        })()}

        {/* Search */}
        <div className="px-6 py-2">
          <SearchInput
            placeholder="Search tools and servers..."
            style={{
              backgroundColor: "#FBFBFF",
              border: "1px solid #E2E2E2",
              color: "#000000",
            }}
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
          />
        </div>

        {/* Tools Section */}

        {/* Content */}
        <div className="px-6 py-2 space-y-4 overflow-y-auto">
          {selectedToolGroup &&
            (() => {
              const actualToolGroup = toolGroups.find(
                (group) => group.id === selectedToolGroup.id,
              );
              if (!actualToolGroup) return null;

              // Get providers that are in this tool group, including providers
              // that no longer exist in the live server list.
              const groupProviders = Object.keys(
                actualToolGroup.services || {},
              ).map((providerName) => {
                const existingProvider = providers.find(
                  (provider) => provider.name === providerName,
                );
                if (existingProvider) return existingProvider;

                return {
                  name: providerName,
                  originalTools: [],
                  state: { type: "connection-failed" as const },
                  icon: undefined,
                  url: "",
                  tools: [],
                  usage: [],
                  headers: {},
                  severity: "error" as const,
                } as unknown as TargetServer;
              });
              const filteredProviders = groupProviders
                .map((provider) => {
                  const toolNames =
                    actualToolGroup.services[provider.name] || [];
                  let providerTools = provider.originalTools.filter((tool) =>
                    toolNames.includes(tool.name ?? ""),
                  );
                  // flag to indicate if the current provider is not connected
                  let providerNotConnected = false;

                  // If no tools match the configured names, show all tools for this provider
                  // This handles cases where tool group was configured with incorrect tool names
                  if (providerTools.length === 0 && toolNames.length > 0) {
                    providerTools = provider.originalTools || [];

                    // If no tools (provider is disconnected/auth required), use fallback for THIS provider
                    providerNotConnected = true;
                  }

                  // Filter tools by search query
                  if (searchQuery) {
                    const searchLower = searchQuery.toLowerCase();

                    // Check if provider name matches search
                    const providerMatches = provider.name
                      .toLowerCase()
                      .includes(searchLower);

                    if (providerNotConnected) {
                      const matchingFallbackToolNames = toolNames.filter(
                        (toolName) =>
                          toolName.toLowerCase().includes(searchLower),
                      );

                      if (
                        !providerMatches &&
                        matchingFallbackToolNames.length === 0
                      ) {
                        return null;
                      }

                      return {
                        provider,
                        tools: providerTools,
                        providerNotConnected,
                        fallbackToolNames: providerMatches
                          ? toolNames
                          : matchingFallbackToolNames,
                      };
                    }

                    // Filter tools by name and description
                    providerTools = providerTools.filter(
                      (tool) =>
                        tool.name.toLowerCase().includes(searchLower) ||
                        (tool.description &&
                          tool.description.toLowerCase().includes(searchLower)),
                    );

                    // If provider name matches but no tools match, still show the provider
                    if (providerMatches && providerTools.length === 0) {
                      providerTools = provider.originalTools.filter((tool) =>
                        toolNames.includes(tool.name),
                      );
                    }
                  }

                  // Don't render provider if no tools match the search (unless provider name matches)
                  if (providerTools.length === 0 && !providerNotConnected)
                    return null;

                  return {
                    provider,
                    tools: providerTools,
                    providerNotConnected,
                    fallbackToolNames: providerNotConnected
                      ? toolNames
                      : undefined,
                  };
                })
                .filter((item) => item !== null);

              // Show "No tools found" message if search query doesn't match anything
              if (searchQuery && filteredProviders.length === 0) {
                return (
                  <div className="text-center py-8">
                    <div className="text-gray-500 text-sm">
                      No tools found matching "{searchQuery}"
                    </div>
                  </div>
                );
              }

              return filteredProviders.map(
                ({
                  provider,
                  tools,
                  providerNotConnected,
                  fallbackToolNames,
                }) => (
                  <div
                    key={provider.name}
                    className="border border-gray-200 rounded-lg p-4 space-y-4 bg-white shadow-xs"
                  >
                    <div className="flex items-center gap-2">
                      <DomainIcon provider={provider} size={32} />
                      <div className="flex-1">
                        <h3 className="capitalize font-semibold text-gray-900 text-lg flex justify-between">
                          {provider.name}
                          {provider.state.type === "pending-auth" && (
                            <span className="bg-yellow-100 text-yellow-800 text-xs px-3 py-1 rounded-full font-medium border border-yellow-200">
                              PENDING AUTH
                            </span>
                          )}
                        </h3>
                      </div>
                    </div>

                    <div className="space-y-2">
                      <p className="text-sm text-foreground">
                        Tools for interacting with the {provider.name} API...
                      </p>
                      {providerNotConnected && (
                        <div className="flex items-center gap-2 text-xs font-semibold leading-[18px] text-[var(--colors-warning-700)]">
                          <TriangleAlert
                            aria-hidden="true"
                            className="size-4 shrink-0"
                            strokeWidth={2}
                          />
                          This server is currently unavailable
                        </div>
                      )}

                      {/* Case when the provider is not connected */}
                      {providerNotConnected &&
                        fallbackToolNames?.map((toolName, toolIndex) => (
                          <div
                            key={toolIndex}
                            className="flex items-center justify-between rounded-lg p-4"
                            style={{
                              backgroundColor: "white",
                              border: "1px solid #E2E2E2",
                            }}
                          >
                            <div className="flex flex-col items-start gap-0.5">
                              <p
                                className="text-foreground"
                                style={{ fontWeight: 600 }}
                              >
                                {toolName}
                              </p>
                            </div>
                          </div>
                        ))}

                      {/* Case when provider is connected descriptions available */}
                      {!providerNotConnected &&
                        tools.map((tool, toolIndex) => (
                          <div
                            key={toolIndex}
                            className="flex items-center justify-between rounded-lg p-4"
                            style={{
                              backgroundColor: "white",
                              border: "1px solid #E2E2E2",
                            }}
                          >
                            <div className="flex flex-col items-start gap-0.5">
                              <p
                                className="text-foreground"
                                style={{ fontWeight: 600 }}
                              >
                                {tool.name}
                              </p>
                              <p
                                className="text-foreground"
                                style={{ fontWeight: 400 }}
                              >
                                {tool.description}
                              </p>
                            </div>
                          </div>
                        ))}
                      <div className="text-xs text-gray-500 mt-2">
                        {(providerNotConnected
                          ? fallbackToolNames?.length
                          : tools.length) || 0}{" "}
                        tool
                        {((providerNotConnected
                          ? fallbackToolNames?.length
                          : tools.length) || 0) !== 1
                          ? "s"
                          : ""}
                      </div>
                    </div>
                  </div>
                ),
              );
            })()}
        </div>
      </SheetContent>
    </Sheet>
  );
}
