"use client"

/**
 * Scope trigger for a product card / marketing hero on the products home.
 *
 * Same menu as the utility bar and sidebar (`ScopeSwitcherMenuBody`) under a
 * wider trigger that names the scope instead of relying on a tooltip — there
 * is no surrounding product chrome here to give the avatar its meaning, so the
 * school and program have to be legible on the face of the control.
 *
 * Three triggers, same menu:
 *
 * - **`card`** — the bordered two-line control on a product card, where scope
 *   is a standing property of the row and has the width to say so.
 * - **`inline`** — one quiet line under a hero's CTA. A card-shaped picker beside
 *   the primary button competed with it: two filled controls, 60px against 44px,
 *   neither obviously the thing to press.
 * - **`compact`** — `inline`'s text with the avatar dropped, for a caption
 *   centered under an icon-grid cell (Launcher). The avatar duplicates the
 *   mark already sitting above it in that context and, at cell width, the
 *   two together left almost no room for the school name before it had to
 *   truncate — the readable-but-unlabelled avatar felt like a stray control
 *   rather than part of one caption.
 *
 * The menu opens **over** the trigger (select-style), matching its width and
 * `rounded-xl` radius so the two do not stack as separate rounded boxes.
 *
 * Writes through shared scope state, so the choice made here is the one the
 * product reports after Open.
 */

import * as React from "react"

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import {
  ScopeSwitcherMenuBody,
  type ScopeSwitcherBag,
} from "@/components/scope-switcher-menu"
import { cn } from "@/lib/utils"

export function ProductScopePicker({
  scope,
  variant = "card",
  className,
}: {
  scope: ScopeSwitcherBag
  variant?: "card" | "inline" | "compact"
  className?: string
}) {
  const inline = variant === "inline"
  const compact = variant === "compact"
  // `inline` and `compact` both read as one line of "Child · Parent" text;
  // only the card variant needs the two-line stack the avatar sits beside.
  const oneLine = inline || compact
  const triggerRef = React.useRef<HTMLButtonElement>(null)
  // Negative bottom offset so the panel top aligns with the trigger top.
  const [coverOffset, setCoverOffset] = React.useState(0)

  React.useLayoutEffect(() => {
    const el = triggerRef.current
    if (!el) return
    const update = () => setCoverOffset(-el.getBoundingClientRect().height)
    update()
    const ro = new ResizeObserver(update)
    ro.observe(el)
    return () => ro.disconnect()
  }, [variant, scope.child.name, scope.parent.name])

  return (
    <DropdownMenu onOpenChange={scope.onOpenChange}>
      <DropdownMenuTrigger asChild>
        <button
          ref={triggerRef}
          type="button"
          aria-label={scope.ariaLabel}
          className={cn(
            "flex items-center text-left transition-colors",
            "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
            inline &&
              // Pill, no fill, no border. It is a qualifier on the button
              // above it, not a second thing to press.
              "max-w-full gap-2 rounded-full py-1.5 pe-2.5 ps-1.5 text-sm text-muted-foreground hover:bg-foreground/6 hover:text-foreground data-[state=open]:bg-foreground/6",
            compact &&
              // No avatar, no fill until pressed — the icon above the cell
              // already anchors the eye, so this is just a smaller, quieter
              // instance of the inline pill's text + chevron.
              "max-w-full gap-1 rounded-full px-1.5 py-1 text-xs text-muted-foreground hover:bg-foreground/6 hover:text-foreground data-[state=open]:bg-foreground/6",
            !inline &&
              !compact &&
              "w-full gap-2.5 rounded-xl border border-border bg-background p-2.5 hover:bg-interactive-hover data-[state=open]:bg-interactive-hover",
            className,
          )}
        >
          {!compact ? (
            <Avatar className={cn("shrink-0", inline ? "size-6" : "size-8")}>
              <AvatarImage
                src={scope.parent.logo}
                alt=""
                referrerPolicy="origin"
                className="object-contain p-0.5"
                aria-hidden="true"
              />
              <AvatarFallback
                className={cn("font-semibold", inline ? "text-[0.625rem]" : "text-xs")}
                aria-hidden="true"
              >
                {scope.parent.initials}
              </AvatarFallback>
            </Avatar>
          ) : null}
          {oneLine ? (
            // One line, school demoted to context. Two stacked lines here would
            // rebuild the card trigger at a smaller size and reintroduce the
            // height mismatch the inline variant exists to remove.
            <span className="min-w-0 truncate">
              <span className="font-medium text-foreground">{scope.child.name}</span>
              <span aria-hidden="true"> · </span>
              {scope.parent.name}
            </span>
          ) : (
            <span className="flex min-w-0 flex-1 flex-col leading-snug">
              <span className="truncate text-sm font-medium">{scope.child.name}</span>
              <span className="truncate text-xs text-muted-foreground">
                {scope.parent.name}
              </span>
            </span>
          )}
          <i
            className="fa-light fa-chevron-down shrink-0 text-xs text-muted-foreground"
            aria-hidden="true"
          />
        </button>
      </DropdownMenuTrigger>

      <DropdownMenuContent
        // Cover the trigger like a select. Width + radius match the field so
        // the open state is one surface, not a second rounded box below it.
        className={cn(
          "rounded-xl",
          "w-(--radix-dropdown-menu-trigger-width) min-w-60 max-w-[min(100vw-2rem,var(--radix-dropdown-menu-trigger-width))]",
          "data-[side=bottom]:slide-in-from-top-0",
        )}
        align="start"
        side="bottom"
        sideOffset={coverOffset}
      >
        <ScopeSwitcherMenuBody scope={scope} />
      </DropdownMenuContent>
    </DropdownMenu>
  )
}
