import React, { ReactNode } from 'react';
import classNames from 'classnames';
import { Icon, IconSrc, as } from 'folds';
import * as css from './Bubble.css';

export type BubbleLayoutProps = {
  // Muted per-message timestamp node (e.g. <Time compact />).
  time?: ReactNode;
  // Own → right bubble; peer → left plain text.
  isOwn?: boolean;
  // Same-sender continuation row — collapse the top gap so a burst clusters.
  collapsed?: boolean;
  // Tap-rail open / context menu open → draw the «selected» ring.
  selected?: boolean;
  // Image/video/voice rows: drop the bubble chrome, the media/voice child owns
  // its visuals.
  mediaMode?: boolean;
  // The timestamp goes BELOW the bubble (rather than on the inner side) — set for
  // media AND for the tail of a same-minute series (grouped messages). A single
  // text message keeps its timestamp on the side.
  timeBelow?: boolean;
  // While editing, the body IS a composer card — drop the bubble chrome so it
  // reads as one box, and skip the timestamp.
  editing?: boolean;
  // Reactions chip-row, floats under the message on the page background.
  reactions?: ReactNode;
  threadSummary?: ReactNode;
  // Read/delivery status line — rendered by the caller only for the last own
  // message (Sending… / Sent / Read / failed).
  readStatus?: ReactNode;
};

// Bubble layout leaf — the simple 1:1 DM look (peer = plain text, own = right
// bubble), matching the AI-bot chat. The surrounding hover/tap menu, reactions
// and reply chrome are supplied by <Message> (the tap-rail floats at the tap
// point, positioned by <Message>); this only arranges the body, the timestamp,
// reactions and the read-status line.
export const BubbleLayout = as<'div', BubbleLayoutProps>(
  (
    {
      className,
      time,
      isOwn,
      collapsed,
      selected,
      mediaMode,
      timeBelow,
      editing,
      reactions,
      threadSummary,
      readStatus,
      children,
      ...props
    },
    ref
  ) => {
    let contentClass = css.PeerText;
    if (mediaMode) contentClass = css.MediaPlain;
    else if (isOwn) contentClass = css.OwnBubble;

    const contentCell = (
      <div className={classNames(contentClass, selected && css.Selected)}>{children}</div>
    );

    let body: ReactNode;
    if (editing) {
      // The child is already a composer card; render it full width, no chrome.
      body = <div className={css.EditContent}>{children}</div>;
    } else if (mediaMode || timeBelow) {
      // Media, and the tail of a same-minute series: timestamp BELOW the content,
      // aligned to the message side by the Row (own → right, peer → left).
      body = (
        <>
          {contentCell}
          {time && <span className={classNames(css.Meta, css.MetaBelow)}>{time}</span>}
        </>
      );
    } else {
      // Single text message: timestamp on the inner side (own → left, peer → right).
      body = (
        <div className={classNames(css.LineWrap, isOwn ? css.LineWrapOwn : css.LineWrapPeer)}>
          {isOwn && time && <span className={classNames(css.Meta, css.MetaSide)}>{time}</span>}
          {contentCell}
          {!isOwn && time && <span className={classNames(css.Meta, css.MetaSide)}>{time}</span>}
        </div>
      );
    }

    return (
      <div
        className={classNames(css.Row({ own: !!isOwn, collapsed: !!collapsed }), className)}
        {...props}
        ref={ref}
      >
        {body}
        {threadSummary && <div className={css.Slot}>{threadSummary}</div>}
        {reactions && <div className={css.Slot}>{reactions}</div>}
        {readStatus && <div className={css.Slot}>{readStatus}</div>}
      </div>
    );
  }
);

export type BubbleSyslineProps = {
  iconSrc: IconSrc;
  content: ReactNode;
  time?: ReactNode;
};

// Rail-less system notice for the bubble DM — a centred, muted one-liner.
export function BubbleSysline({ iconSrc, content, time }: BubbleSyslineProps) {
  return (
    <div className={css.Sysline}>
      <Icon className={css.SyslineIcon} size="50" src={iconSrc} />
      <div className={css.SyslineBody}>{content}</div>
      {time && <span className={css.SyslineTime}>{time}</span>}
    </div>
  );
}
