"use client";
import * as React from 'react';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { cva } from 'class-variance-authority';
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';

function cn(...inputs) {
  return twMerge(clsx(inputs));
}
var SAFE_URL_SCHEMES = ["http:", "https:", "mailto:"];
function safeUrl(raw) {
  if (raw === void 0 || raw === "") return void 0;
  let parsed;
  try {
    parsed = new URL(raw);
  } catch {
    return raw.includes(":") ? void 0 : raw;
  }
  return SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : void 0;
}
function Composer({
  value,
  onValueChange,
  onSubmit,
  disabled,
  placeholder,
  submitOnEnter = true,
  textareaAriaLabel,
  children,
  className,
  ...rest
}) {
  function trySubmit() {
    const trimmed = value.trim();
    if (!trimmed || disabled) return;
    onSubmit(trimmed);
  }
  function handleKeyDown(event) {
    if (!submitOnEnter) return;
    if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
      event.preventDefault();
      trySubmit();
    }
  }
  function handleSubmit(event) {
    event.preventDefault();
    trySubmit();
  }
  return /* @__PURE__ */ jsxs(
    "form",
    {
      ...rest,
      onSubmit: handleSubmit,
      className: cn(
        "flex items-end gap-2 rounded-lg border bg-background p-2",
        "focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
        "transition-all duration-[var(--duration-normal,200ms)] ease-out",
        className
      ),
      children: [
        /* @__PURE__ */ jsx(
          "textarea",
          {
            value,
            onChange: (event) => onValueChange(event.target.value),
            onKeyDown: handleKeyDown,
            disabled,
            placeholder,
            "aria-label": textareaAriaLabel ?? placeholder ?? "Message",
            rows: 1,
            className: cn(
              "flex-1 resize-none bg-transparent px-2 py-1.5 text-sm leading-6",
              "placeholder:text-muted-foreground focus:outline-none",
              "disabled:cursor-not-allowed disabled:opacity-50",
              "max-h-48 min-h-[2.25rem] overflow-y-auto"
            )
          }
        ),
        children
      ]
    }
  );
}
var messageVariants = cva(
  [
    "flex w-full gap-3 px-4 py-3 text-sm",
    "transition-colors duration-[var(--duration-normal,200ms)] ease-out"
  ].join(" "),
  {
    variants: {
      role: {
        user: "bg-secondary/40 text-foreground",
        assistant: "bg-card text-card-foreground",
        system: "bg-muted text-muted-foreground italic",
        tool: "bg-accent/15 text-accent-foreground border-l-2 border-accent"
      }
    },
    defaultVariants: {
      role: "assistant"
    }
  }
);
function Message({ role, className, children, ...props }) {
  return /* @__PURE__ */ jsx("div", { "data-role": role, className: cn(messageVariants({ role }), className), ...props, children });
}
var NEAR_BOTTOM_THRESHOLD_PX = 80;
function MessageList({
  autoScroll = true,
  className,
  children,
  ...props
}) {
  const ref = React.useRef(null);
  const stickToBottomRef = React.useRef(true);
  React.useEffect(() => {
    const el = ref.current;
    if (!el || !autoScroll) return;
    if (stickToBottomRef.current) {
      el.scrollTop = el.scrollHeight;
    }
  }, [autoScroll, children]);
  function handleScroll(event) {
    const el = event.currentTarget;
    const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
    stickToBottomRef.current = distance < NEAR_BOTTOM_THRESHOLD_PX;
    props.onScroll?.(event);
  }
  return /* @__PURE__ */ jsx(
    "div",
    {
      ref,
      role: "log",
      "aria-live": "polite",
      "aria-relevant": "additions",
      className: cn("flex flex-col overflow-y-auto", className),
      ...props,
      onScroll: handleScroll,
      children
    }
  );
}
function Shimmer({
  width = "100%",
  height = "1.5rem",
  durationMs = 1500,
  label = "Loading\u2026",
  className
}) {
  return /* @__PURE__ */ jsx(
    "div",
    {
      role: "status",
      "aria-label": label,
      "aria-live": "polite",
      className: cn(
        // `motion-safe:` gates the pulse on `prefers-reduced-motion: no-preference` —
        // users with reduce-motion get a static bar.
        "motion-safe:animate-pulse rounded-md border border-foreground/[0.06] bg-muted",
        className
      ),
      style: {
        width,
        height,
        animationDuration: `${durationMs}ms`
      }
    }
  );
}
function Citation({ title, url, page, index, className, children }) {
  const baseClasses = cn(
    "inline-flex items-center gap-1.5 rounded-md border border-foreground/15 bg-card px-2 py-0.5 text-xs",
    "transition-all duration-[var(--duration-normal,200ms)] ease-out",
    className
  );
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
    typeof index === "number" ? /* @__PURE__ */ jsxs("span", { className: "font-mono text-[10px] font-semibold text-muted-foreground", children: [
      "[",
      index,
      "]"
    ] }) : /* @__PURE__ */ jsx(DocGlyph, {}),
    /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: title }),
    typeof page === "number" ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
      "p.",
      page
    ] }) : null,
    children
  ] });
  if (url) {
    return /* @__PURE__ */ jsx(
      "a",
      {
        href: url,
        target: "_blank",
        rel: "noreferrer noopener",
        className: cn(
          baseClasses,
          "hover:border-foreground/30 hover:bg-secondary/40 hover:shadow-sm",
          "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
        ),
        children: body
      }
    );
  }
  return /* @__PURE__ */ jsx("span", { className: baseClasses, children: body });
}
function DocGlyph() {
  return /* @__PURE__ */ jsxs(
    "svg",
    {
      "aria-hidden": true,
      viewBox: "0 0 16 16",
      width: "11",
      height: "11",
      fill: "none",
      stroke: "currentColor",
      strokeWidth: "1.5",
      strokeLinecap: "round",
      strokeLinejoin: "round",
      className: "shrink-0 text-muted-foreground",
      children: [
        /* @__PURE__ */ jsx("path", { d: "M9 1.5H4.5A1.5 1.5 0 0 0 3 3v10a1.5 1.5 0 0 0 1.5 1.5h7A1.5 1.5 0 0 0 13 13V5.5L9 1.5z" }),
        /* @__PURE__ */ jsx("path", { d: "M9 1.5V5.5h4" })
      ]
    }
  );
}
function Sources({ sources, defaultOpen = true, className }) {
  if (sources.length === 0) return null;
  const count = sources.length;
  const headerLabel = count === 1 ? "1 source" : `${count} sources`;
  return /* @__PURE__ */ jsxs(
    CollapsiblePrimitive.Root,
    {
      defaultOpen,
      className: cn(
        "overflow-hidden rounded-md border border-border bg-card text-card-foreground",
        className
      ),
      children: [
        /* @__PURE__ */ jsxs(
          CollapsiblePrimitive.Trigger,
          {
            className: cn(
              "group flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-muted-foreground",
              "transition-all duration-[var(--duration-normal,200ms)] ease-out",
              "hover:text-foreground",
              "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
            ),
            children: [
              /* @__PURE__ */ jsx(DocStackGlyph, {}),
              /* @__PURE__ */ jsx("span", { className: "font-medium", children: headerLabel }),
              /* @__PURE__ */ jsx(Chevron, {})
            ]
          }
        ),
        /* @__PURE__ */ jsx(CollapsiblePrimitive.Content, { className: "overflow-hidden border-t border-foreground/[0.06]", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1.5 p-2", children: sources.map((s, i) => /* @__PURE__ */ jsx(
          Citation,
          {
            title: s.title,
            url: safeUrl(s.url),
            page: s.page,
            index: s.index ?? i + 1
          },
          `${s.url ?? s.title}-${i}`
        )) }) })
      ]
    }
  );
}
function DocStackGlyph() {
  return /* @__PURE__ */ jsxs(
    "svg",
    {
      "aria-hidden": true,
      viewBox: "0 0 16 16",
      width: "12",
      height: "12",
      fill: "none",
      stroke: "currentColor",
      strokeWidth: "1.5",
      strokeLinecap: "round",
      strokeLinejoin: "round",
      className: "shrink-0",
      children: [
        /* @__PURE__ */ jsx("path", { d: "M5 3h7l1.5 1.5V13H5V3z" }),
        /* @__PURE__ */ jsx("path", { d: "M3 5v8.5L4.5 15H11" })
      ]
    }
  );
}
function Chevron() {
  return /* @__PURE__ */ jsx(
    "svg",
    {
      "aria-hidden": true,
      viewBox: "0 0 16 16",
      width: "12",
      height: "12",
      fill: "none",
      stroke: "currentColor",
      strokeWidth: "1.5",
      strokeLinecap: "round",
      strokeLinejoin: "round",
      className: "ml-auto shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-180",
      children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
    }
  );
}
function Conversation({
  messages,
  onSubmit,
  placeholder = "Ask anything\u2026",
  value: valueProp,
  onValueChange: onValueChangeProp,
  isStreaming = false,
  sources,
  disabled = false,
  composerActions,
  className
}) {
  const [internalValue, setInternalValue] = React.useState("");
  const isControlled = valueProp !== void 0;
  const value = isControlled ? valueProp : internalValue;
  const setValue = isControlled ? (next) => onValueChangeProp?.(next) : setInternalValue;
  if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production" && isControlled && typeof onValueChangeProp !== "function") {
    console.warn(
      "<Conversation>: `value` was passed without `onValueChange`. The composer will be read-only \u2014 pass both props together for controlled mode, or omit both to let the component manage state internally."
    );
  }
  function handleSubmit(text) {
    onSubmit(text);
    setValue("");
  }
  return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 flex-col gap-3", className), children: [
    /* @__PURE__ */ jsxs(MessageList, { className: "min-h-0 flex-1", children: [
      messages.map((m) => /* @__PURE__ */ jsx(Message, { role: m.role, children: m.content }, m.id)),
      isStreaming ? /* @__PURE__ */ jsx(Message, { role: "assistant", children: /* @__PURE__ */ jsx(Shimmer, { width: "60%" }) }) : null
    ] }),
    sources && sources.length > 0 ? /* @__PURE__ */ jsx(Sources, { sources }) : null,
    /* @__PURE__ */ jsx(
      Composer,
      {
        value,
        onValueChange: setValue,
        onSubmit: handleSubmit,
        disabled,
        placeholder,
        children: composerActions
      }
    )
  ] });
}

export { Conversation };
//# sourceMappingURL=conversation.js.map
//# sourceMappingURL=conversation.js.map