import {
  Button,
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger
} from "@ai-ui/ui";
import type { Meta, StoryObj } from "@storybook/react";

async function waitForCondition(
  predicate: () => boolean,
  message: string,
  timeoutMs = 1500
) {
  const startedAt = Date.now();

  while (Date.now() - startedAt < timeoutMs) {
    if (predicate()) {
      return;
    }

    await new Promise((resolve) => window.setTimeout(resolve, 16));
  }

  throw new Error(message);
}

type ReleaseMenuProps = {
  triggerLabel?: string;
};

function ReleaseMenu({ triggerLabel = "Open menu" }: ReleaseMenuProps) {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="secondary">{triggerLabel}</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuLabel>Launch actions</DropdownMenuLabel>
        <DropdownMenuItem>
          Review summary
          <DropdownMenuShortcut>R</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuItem>
          Share preview
          <DropdownMenuShortcut>S</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuItem disabled>
          Retry checks
          <DropdownMenuShortcut>⌘R</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuCheckboxItem checked>Notify stakeholders</DropdownMenuCheckboxItem>
        <DropdownMenuSeparator />
        <DropdownMenuRadioGroup value="staged">
          <DropdownMenuRadioItem value="staged">Staged rollout</DropdownMenuRadioItem>
          <DropdownMenuRadioItem value="global">Global rollout</DropdownMenuRadioItem>
        </DropdownMenuRadioGroup>
        <DropdownMenuSeparator />
        <DropdownMenuSub>
          <DropdownMenuSubTrigger inset>More actions</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            <DropdownMenuItem>Duplicate release</DropdownMenuItem>
            <DropdownMenuItem variant="destructive">Archive release</DropdownMenuItem>
          </DropdownMenuSubContent>
        </DropdownMenuSub>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

const meta = {
  title: "Components/DropdownMenu",
  component: DropdownMenu,
  parameters: {
    docs: {
      description: {
        component:
          "DropdownMenu is the compact action surface for contextual commands, quick toggles, and short decision trees. It supports labels, separators, nested submenus, checkbox and radio items, destructive emphasis, and keyboard-first navigation without introducing a separate API style."
      }
    },
    layout: "centered"
  },
  tags: ["autodocs"]
} satisfies Meta<typeof DropdownMenu>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Playground: Story = {
  render: () => <ReleaseMenu />,
  play: async ({ canvasElement }) => {
    const trigger = [...canvasElement.querySelectorAll("button")].find((element) =>
      element.textContent?.includes("Open menu")
    );

    if (!(trigger instanceof HTMLButtonElement)) {
      throw new Error("Expected the dropdown trigger to render.");
    }

    trigger.click();

    await waitForCondition(
      () => document.body.querySelector('[role="menu"]') instanceof HTMLElement,
      "Expected the dropdown menu to open."
    );

    const item = [...document.body.querySelectorAll('[role="menuitem"]')].find((element) =>
      element.textContent?.includes("Review summary")
    );

    if (!(item instanceof HTMLElement)) {
      throw new Error("Expected the Review summary item to render.");
    }

    item.click();

    await waitForCondition(
      () => document.body.querySelector('[role="menu"]') === null,
      "Expected the dropdown menu to close after selection."
    );
  }
};

export const States: Story = {
  parameters: {
    docs: {
      description: {
        story:
          "Open the menu to inspect the checked checkbox item, the selected radio item, a disabled action, the inset submenu trigger, and the destructive nested action."
      }
    }
  },
  render: () => (
    <div className="grid w-[680px] gap-3 sm:grid-cols-2">
      <ReleaseMenu triggerLabel="Review lane menu" />
      <ReleaseMenu triggerLabel="Launch action menu" />
    </div>
  )
};

export const Anatomy: Story = {
  render: () => (
    <div className="w-[720px] rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-card)] p-6 text-[var(--color-foreground)] shadow-[var(--shadow-sm)]">
      <div className="space-y-3">
        <p className="text-xs uppercase tracking-[var(--tracking-caps)] text-[var(--color-muted-foreground)]">
          Dropdown menu anatomy
        </p>
        <ReleaseMenu triggerLabel="Inspect menu structure" />
        <div className="grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
          <p>
            <code className="text-[var(--color-foreground)]">data-slot="content"</code> frames
            the floating panel and exposes sizing for denser menus.
          </p>
          <p>
            <code className="text-[var(--color-foreground)]">data-slot="item"</code>,{" "}
            <code className="text-[var(--color-foreground)]">data-slot="trigger"</code>, and{" "}
            <code className="text-[var(--color-foreground)]">data-slot="shortcut"</code> map the
            action rows, nested trigger, and keyboard hint.
          </p>
          <p>
            <code className="text-[var(--color-foreground)]">data-slot="label"</code>,{" "}
            <code className="text-[var(--color-foreground)]">data-slot="separator"</code>, and{" "}
            <code className="text-[var(--color-foreground)]">data-slot="icon"</code> support
            grouping, dividers, and selection markers.
          </p>
        </div>
      </div>
    </div>
  )
};

export const Accessibility: Story = {
  parameters: {
    docs: {
      description: {
        story:
          "Dropdown menus are optimized for keyboard and pointer parity. Focus moves with arrow keys, typeahead remains available through Radix semantics, and destructive options should stay visually distinct from neutral commands."
      }
    }
  },
  render: () => (
    <div className="grid w-[760px] gap-4 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]">
      <article className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-card)] p-6 shadow-[var(--shadow-sm)]">
        <h3 className="text-lg font-semibold tracking-[var(--tracking-tight)]">
          Keyboard guidance
        </h3>
        <div className="mt-4 grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
          <p>Use labels and separators to group commands into short scannable clusters.</p>
          <p>
            Keep checkbox and radio items in menus only when the state change is immediate
            and local to the current context.
          </p>
          <p>
            Prefer concise labels. Long explanatory copy belongs in a dialog or popover,
            not in a menu row.
          </p>
        </div>
      </article>
      <div className="flex items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-[var(--color-border-strong)] bg-[var(--color-background)] p-6">
        <ReleaseMenu triggerLabel="Open keyboard-friendly menu" />
      </div>
    </div>
  )
};
