import { PromptDetailsView } from "@/components/details/prompt/index.tsx";
import { ToolDetailsView } from "@/components/details/tool.tsx";
import { ErrorBoundary } from "@/components/error-boundary";
import {
  useCollectionActions,
  useConnections,
  useMCPClient,
  useProjectContext,
} from "@/sdk";

import { EmptyState } from "@decocms/ui/components/empty-state.tsx";
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@decocms/ui/components/breadcrumb.tsx";
import { Loading01, Container } from "@untitledui/icons";
import { Link, useParams, useRouter } from "@tanstack/react-router";
import { Suspense, type ComponentType } from "react";
import { ViewLayout } from "@/components/details/layout";
import { useT } from "@/i18n/use-t.ts";

interface CollectionDetailsProps {
  itemId: string;
  onBack: () => void;
  onUpdate: (updates: Record<string, unknown>) => Promise<void>;
}

// Map of well-known views by collection name
const WELL_KNOWN_VIEW_DETAILS: Record<
  string,
  ComponentType<CollectionDetailsProps>
> = {
  prompt: PromptDetailsView,
};

function ToolDetailsContent() {
  const router = useRouter();
  const params = useParams({
    from: "/shell/$org/settings/connections/$appSlug/$collectionName/$itemId",
  });

  const itemId = decodeURIComponent(params.itemId);

  const siblings = useConnections({ slug: params.appSlug });

  const handleBack = () => {
    router.history.back();
  };

  const handleUpdate = async (_updates: Record<string, unknown>) => {
    // Tools don't use collections, so updates are handled by ToolDetailsView
    // This is a no-op for tools since they don't have collection-based updates
    return Promise.resolve();
  };

  return (
    <ToolDetailsView
      itemId={itemId}
      siblings={siblings}
      onBack={handleBack}
      onUpdate={handleUpdate}
    />
  );
}

/**
 * Formats a collection name for display
 * e.g., "LLM" -> "Llm", "USER_PROFILES" -> "User Profiles"
 */
function formatCollectionName(name: string): string {
  return name
    .toLowerCase()
    .split("_")
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(" ");
}

function CollectionDetailsContent() {
  const router = useRouter();
  const params = useParams({
    from: "/shell/$org/settings/connections/$appSlug/$collectionName/$itemId",
  });

  const t = useT();
  const collectionName = decodeURIComponent(params.collectionName);
  const itemId = decodeURIComponent(params.itemId);

  const handleBack = () => {
    router.history.back();
  };

  const { org } = useProjectContext();
  const slugConnections = useConnections({ slug: params.appSlug });
  const connection = slugConnections[0] ?? null;
  const connectionId = connection?.id ?? "";
  const scopeKey = connectionId || "no-connection";
  const client = useMCPClient({
    connectionId: connectionId ?? null,
    orgId: org.id,
    orgSlug: org.slug,
  });

  const actions = useCollectionActions(scopeKey, collectionName, client);

  const handleUpdate = async (updates: Record<string, unknown>) => {
    if (!itemId) return;
    await actions.update.mutateAsync({
      id: itemId,
      data: updates,
    });
    // Success/error toasts are handled by the mutation's onSuccess/onError
  };

  // Check for well-known collections (case insensitive, singular/plural)
  const normalizedCollectionName = collectionName?.toLowerCase();

  const ViewComponent =
    normalizedCollectionName &&
    WELL_KNOWN_VIEW_DETAILS[normalizedCollectionName];

  const collectionDisplayName = formatCollectionName(collectionName);

  const breadcrumb = (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink asChild>
            <Link to="/$org/settings/connections" params={{ org: org.slug }}>
              Connections
            </Link>
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        {connection && (
          <>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link
                  to="/$org/settings/connections/$appSlug"
                  params={{
                    org: org.slug,
                    appSlug: params.appSlug,
                  }}
                  search={{ tab: collectionName }}
                >
                  {connection.title}
                </Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
          </>
        )}
        <BreadcrumbItem>
          <BreadcrumbPage>{collectionDisplayName}</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );

  if (ViewComponent) {
    return (
      <ViewComponent
        itemId={itemId}
        onBack={handleBack}
        onUpdate={handleUpdate}
      />
    );
  }

  return (
    <ViewLayout breadcrumb={breadcrumb}>
      <EmptyState
        icon={<Container size={36} className="text-muted-foreground" />}
        title={t("orgs.collectionDetail.noComponentDefinedTitle")}
        description={t("orgs.collectionDetail.noComponentDefinedDescription")}
        buttonProps={{
          onClick: handleBack,
          children: t("orgs.collectionDetail.goBackButton"),
        }}
      />
    </ViewLayout>
  );
}

function CollectionDetailsRouter() {
  const params = useParams({
    from: "/shell/$org/settings/connections/$appSlug/$collectionName/$itemId",
  });

  const collectionName = decodeURIComponent(params.collectionName);

  const isTools = collectionName === "tools";

  if (isTools) {
    return <ToolDetailsContent />;
  }

  return <CollectionDetailsContent />;
}

export default function CollectionDetails() {
  return (
    <ErrorBoundary>
      <Suspense
        fallback={
          <div className="flex h-full items-center justify-center">
            <Loading01
              size={32}
              className="animate-spin text-muted-foreground"
              aria-label={useT()("orgs.collectionDetail.loadingAriaLabel")}
            />
          </div>
        }
      >
        <CollectionDetailsRouter />
      </Suspense>
    </ErrorBoundary>
  );
}
