import { useEffect } from "react";
import { Link, useNavigate } from "@tanstack/react-router";
import { useAtomValue, useAtomRefresh } from "@effect/atom-react";
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
import { IntegrationSlug } from "@executor-js/sdk/shared";

import { integrationAtom, integrationsOptimisticAtom } from "../api/atoms";
import { ErrorState } from "../components/error-state";
import { Skeleton } from "../components/skeleton";
import { isAsyncResultLoading } from "../lib/async-result";
import { useExecutorDocumentTitle } from "../lib/document-title";

// ---------------------------------------------------------------------------
// `/connect/<integration slug>` — the stable, shareable deep link that drops a
// person straight into the connect flow for ONE integration ("connect your
// Linear") instead of the dashboard.
//
// This page owns no connect UI of its own. It resolves the slug against the
// tenant's catalog and forwards into the integration detail page's existing
// account handoff (`?addAccount=1`), which is the same surface the detail
// page's own "Add connection" button opens — multi-method tab strips, OAuth
// popups, existing-connection lists and "add another account" all come for
// free, and stay correct as that flow evolves.
//
// Deliberately keyed on the INTEGRATION SLUG, not a plugin id: the slug is the
// catalog identity a customer can write down, whereas plugin routes are on
// their way out. The redirect is `replace: true` so the deep link does not
// linger in history and Back leaves the connect flow rather than bouncing.
// ---------------------------------------------------------------------------

export function ConnectIntegrationPage(props: { readonly integrationSlug: string }) {
  const { integrationSlug } = props;
  const slug = IntegrationSlug.make(integrationSlug);
  const integration = useAtomValue(integrationAtom(slug));
  const refreshIntegrations = useAtomRefresh(integrationsOptimisticAtom);
  const navigate = useNavigate();

  useExecutorDocumentTitle("Connect");

  // The catalog read is a client-side find over the integrations list, so an
  // unknown slug resolves to Success(null) rather than a failure — the missing
  // case is a not-found state, and only a genuine fetch failure is an error.
  const resolved = AsyncResult.isSuccess(integration) ? integration.value : null;
  const loading = isAsyncResultLoading(integration);
  const failed = AsyncResult.isFailure(integration);
  const missing = !loading && !failed && resolved === null;

  useEffect(() => {
    if (resolved === null) return;
    void navigate({
      to: "/{-$orgSlug}/integrations/$namespace",
      params: { namespace: String(resolved.slug) },
      // The NUMBER 1, so the router serializes the canonical `?addAccount=1`
      // that agent-generated handoff links already use (a string would be
      // quoted as `%221%22`).
      search: { tab: "accounts", addAccount: 1 },
      replace: true,
    });
  }, [resolved, navigate]);

  if (failed) {
    return (
      <ConnectStateFrame>
        <ErrorState message="Failed to load integrations" onRetry={refreshIntegrations} />
      </ConnectStateFrame>
    );
  }

  if (missing) {
    return (
      <ConnectStateFrame>
        <div className="flex flex-col items-center justify-center rounded-2xl border border-dashed border-border py-20">
          <p className="mb-1 text-sm font-medium text-foreground/70">
            Unknown integration: {integrationSlug}
          </p>
          <p className="mb-5 text-xs text-muted-foreground">
            This integration is not in your workspace.
          </p>
          <Link
            to="/{-$orgSlug}"
            className="inline-flex items-center gap-1.5 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90"
          >
            Back to integrations
          </Link>
        </div>
      </ConnectStateFrame>
    );
  }

  // Loading, or resolved and mid-redirect: the same quiet placeholder, so the
  // hand-off never flashes an empty frame between catalog load and navigation.
  return (
    <ConnectStateFrame>
      <div className="space-y-3">
        <Skeleton className="h-8 w-56" />
        <Skeleton className="h-4 w-80" />
        <Skeleton className="h-32 w-full" />
      </div>
    </ConnectStateFrame>
  );
}

function ConnectStateFrame(props: { readonly children: React.ReactNode }) {
  return (
    <div className="relative min-h-0 flex-1 overflow-y-auto">
      <div className="mx-auto max-w-4xl px-6 py-10 lg:px-10 lg:py-14">{props.children}</div>
    </div>
  );
}
