'use client';

import type { ReactNode } from 'react';

import { cn } from '@djangocfg/ui-core/lib';

/**
 * SuggestedPrompts — chat empty-state "starter prompts" surface.
 *
 * The pattern every chat consumer wants: a small hero (optional), a
 * title + description (optional), and a row/grid of clickable prompts
 * that seed the composer. Pluggable enough to cover ChatGPT-style
 * card grids and cmdop-style flat chips with the same component.
 *
 * Typical wiring inside `<ChatRoot slots={{ empty: ({ setValue, focus }) =>
 *   <SuggestedPrompts items={...} onPick={(p) => { setValue(p.prompt); focus(); }} />
 * }} />`.
 */

export type SuggestedPromptItem = {
  id: string;
  /** Displayed on the chip / card. */
  label: string;
  /** Sent on click (often equal to `label`). */
  prompt: string;
  /** Optional leading icon. */
  icon?: ReactNode;
  /** Optional secondary line (rendered in `grid` layout, ignored by `chips`). */
  description?: string;
};

export type SuggestedPromptsLayout = 'chips' | 'grid';

export interface SuggestedPromptsProps {
  items: readonly SuggestedPromptItem[];
  onPick: (item: SuggestedPromptItem) => void;
  /** Optional title above the chips. */
  title?: ReactNode;
  /** Optional subtitle/description above the chips. */
  description?: ReactNode;
  /** Optional hero element above the title (icon, logo, …). */
  hero?: ReactNode;
  /** Layout — `chips` (flat rounded-full buttons, default) or `grid` (2-col cards). */
  layout?: SuggestedPromptsLayout;
  /** Container className. */
  className?: string;
  /** ARIA label for the region wrapper. Default `Suggested prompts`. */
  ariaLabel?: string;
  /** Custom render override for one item (escape hatch). */
  renderItem?: (item: SuggestedPromptItem, idx: number) => ReactNode;
}

export function SuggestedPrompts({
  items,
  onPick,
  title,
  description,
  hero,
  layout = 'chips',
  className,
  ariaLabel = 'Suggested prompts',
  renderItem,
}: SuggestedPromptsProps) {
  const hasHeader = hero != null || title != null || description != null;

  return (
    <section
      role="region"
      aria-label={ariaLabel}
      className={cn(
        'flex w-full flex-col items-center text-center',
        className,
      )}
    >
      {hasHeader ? (
        <div className="mb-4 flex flex-col items-center gap-1.5">
          {hero != null ? (
            <div className="text-foreground/90">{hero}</div>
          ) : null}
          {title != null ? (
            <h3 className="text-base font-semibold text-foreground">
              {title}
            </h3>
          ) : null}
          {description != null ? (
            <p className="max-w-md text-sm leading-snug text-muted-foreground">
              {description}
            </p>
          ) : null}
        </div>
      ) : null}

      {layout === 'grid' ? (
        <div
          className="grid w-full max-w-xl grid-cols-1 gap-2 sm:grid-cols-2"
          role="list"
        >
          {items.map((item, idx) =>
            renderItem ? (
              <span key={item.id} role="listitem">
                {renderItem(item, idx)}
              </span>
            ) : (
              <GridCard key={item.id} item={item} onPick={onPick} />
            ),
          )}
        </div>
      ) : (
        <div
          className="flex w-full max-w-xl flex-wrap justify-center gap-2"
          role="list"
        >
          {items.map((item, idx) =>
            renderItem ? (
              <span key={item.id} role="listitem">
                {renderItem(item, idx)}
              </span>
            ) : (
              <Chip key={item.id} item={item} onPick={onPick} />
            ),
          )}
        </div>
      )}
    </section>
  );
}

function Chip({
  item,
  onPick,
}: {
  item: SuggestedPromptItem;
  onPick: (item: SuggestedPromptItem) => void;
}) {
  return (
    <button
      type="button"
      role="listitem"
      onClick={() => onPick(item)}
      className={cn(
        'inline-flex items-center gap-1.5 rounded-full border border-border',
        'bg-card/60 px-3 py-1.5 text-xs text-muted-foreground',
        'transition-colors duration-150',
        'hover:border-primary/40 hover:bg-card hover:text-foreground',
        'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
        'active:scale-[0.97]',
      )}
    >
      {item.icon != null ? (
        <span aria-hidden className="shrink-0 text-muted-foreground">
          {item.icon}
        </span>
      ) : null}
      <span>{item.label}</span>
    </button>
  );
}

function GridCard({
  item,
  onPick,
}: {
  item: SuggestedPromptItem;
  onPick: (item: SuggestedPromptItem) => void;
}) {
  return (
    <button
      type="button"
      role="listitem"
      onClick={() => onPick(item)}
      className={cn(
        'group flex flex-col gap-1 rounded-md border border-border',
        'bg-card/60 p-3 text-left',
        'transition-colors duration-150',
        'hover:border-primary/40 hover:bg-card',
        'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
      )}
    >
      <span className="flex items-center gap-2 text-sm font-medium text-foreground">
        {item.icon != null ? (
          <span aria-hidden className="shrink-0 text-muted-foreground group-hover:text-foreground">
            {item.icon}
          </span>
        ) : null}
        <span>{item.label}</span>
      </span>
      {item.description ? (
        <span className="text-xs leading-snug text-muted-foreground">
          {item.description}
        </span>
      ) : null}
    </button>
  );
}
