// [nexus] Phase 12 — PromoteTransition.
//
// CSS-first animation container that drives the 700ms compress-and-rise
// moment from spec §5.6. When `state` is `prompting` or `creating`:
//
//   0–200ms  : chat ribbon collapses 100% → 30vh (inset shadow fades in)
//   200–500ms: brainstormer panel slides up from below into bottom 70%
//   500–700ms: SOURCE CONVERSATION label fades in above the ribbon
//
// On `idle` / `done` the overlay unmounts. `prefers-reduced-motion` is
// honored via inline CSS — transitions are set to `none`.
//
// This component is intentionally CSS-only; no motion library dependency.
import { useEffect, useRef } from "react";
import { cn } from "@/lib/utils";

export type PromoteTransitionState = "idle" | "prompting" | "creating" | "done" | "error";

export interface PromoteTransitionProps {
  /** The hook's promote state kind. */
  state: PromoteTransitionState;
  /**
   * The compressed chat ribbon. Caller passes whatever the source view
   * should look like — usually the current ChatMessageList in a scrollable
   * container.
   */
  children: React.ReactNode;
  /**
   * The rising brainstormer panel content. Usually <BrainstormerPanel />.
   */
  panelChildren: React.ReactNode;
  className?: string;
}

// Inlined styles for the transition so we do NOT need to touch the global
// stylesheet. A <style> tag is rendered once per overlay mount and scopes
// via a class name.
const TRANSITION_STYLE = `
.nx-promote-ribbon {
  position: relative;
  overflow: hidden;
  max-height: 100%;
  transition: max-height 200ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 200ms ease-out;
  box-shadow: none;
}
.nx-promote-ribbon[data-pstate="prompting"],
.nx-promote-ribbon[data-pstate="creating"] {
  max-height: 30vh;
  box-shadow: inset 0 -16px 24px -12px rgba(0, 0, 0, 0.55);
}
.nx-promote-panel {
  transform: translateY(100%);
  opacity: 0;
  transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
              opacity 300ms ease-out;
  transition-delay: 0ms;
}
.nx-promote-panel[data-pstate="prompting"],
.nx-promote-panel[data-pstate="creating"] {
  transform: translateY(0);
  opacity: 1;
  transition-delay: 200ms;
}
.nx-promote-label {
  opacity: 0;
  transition: opacity 200ms ease-out;
  transition-delay: 0ms;
}
.nx-promote-label[data-pstate="prompting"],
.nx-promote-label[data-pstate="creating"] {
  opacity: 1;
  transition-delay: 500ms;
}
@media (prefers-reduced-motion: reduce) {
  .nx-promote-ribbon,
  .nx-promote-panel,
  .nx-promote-label {
    transition: none !important;
  }
}
/* Phase 15: on mobile the brainstormer completely covers the chat
   instead of rendering a 30/70 split. The ribbon and source label are
   hidden; the panel takes the full viewport height. Single 768px
   breakpoint matches the rest of the Nexus frame. */
@media (max-width: 767px) {
  .nx-promote-ribbon[data-pstate="prompting"],
  .nx-promote-ribbon[data-pstate="creating"] {
    max-height: 0;
    box-shadow: none;
    overflow: hidden;
  }
  .nx-promote-label[data-pstate="prompting"],
  .nx-promote-label[data-pstate="creating"] {
    display: none;
  }
}
`;

export function PromoteTransition({
  state,
  children,
  panelChildren,
  className,
}: PromoteTransitionProps) {
  const rootRef = useRef<HTMLDivElement>(null);

  // When the transition first mounts (state flipped to prompting), move
  // focus to the overlay so screen readers announce the aria-live region.
  useEffect(() => {
    if (state === "prompting" || state === "creating") {
      rootRef.current?.focus();
    }
  }, [state]);

  if (state === "idle" || state === "done" || state === "error") {
    return null;
  }

  return (
    <div
      ref={rootRef}
      tabIndex={-1}
      data-testid="promote-transition"
      data-state={state}
      aria-live="polite"
      role="region"
      aria-label="Promote to project"
      className={cn(
        "absolute inset-0 z-40 flex flex-col bg-background",
        className,
      )}
    >
      <style>{TRANSITION_STYLE}</style>

      {/* SOURCE CONVERSATION label */}
      <div
        data-testid="promote-source-label"
        data-pstate={state}
        className="nx-promote-label px-6 pt-3 text-[10px] uppercase tracking-[0.14em] text-muted-foreground"
      >
        Source Conversation
      </div>

      {/* Compressed chat ribbon */}
      <div
        data-testid="promote-chat-ribbon"
        data-pstate={state}
        className="nx-promote-ribbon flex-shrink-0 px-6 py-2"
      >
        {children}
      </div>

      {/* Rising brainstormer panel */}
      <div
        data-testid="promote-panel-container"
        data-pstate={state}
        className="nx-promote-panel relative flex-1 min-h-0"
      >
        {panelChildren}
      </div>
    </div>
  );
}
