import React, { ReactNode, useRef } from 'react';
import { toRem } from 'folds';
import { StreamMediaBubble } from './StreamMedia.css';
import { logMedia, useMediaMeasureDebug } from './streamMediaDebug';

// Timeline media preview box — shrunk ~1.9× from the original 320 per
// design so photos/videos read as compact inline previews; the full
// image opens in the media viewer on tap.
const STREAM_MEDIA_MAX_DIM = 168;
const STREAM_MEDIA_MIN_ASPECT = 3 / 4;
const STREAM_MEDIA_MAX_ASPECT = 4 / 3;

export type StreamMediaShellProps = {
  naturalW?: number;
  naturalH?: number;
  own: boolean;
  children: ReactNode;
};

function computeBoxStyle(naturalW?: number, naturalH?: number): React.CSSProperties {
  // Explicit pixel width + height — required so the inner content (folds
  // ImageContent / VideoContent — `RelativeBase` with `height: 100%`) gets
  // a definite parent height to resolve against. `max-width: 100%` from
  // StreamMediaBubble + the surrounding StreamBubble's mediaMode
  // `display: block; width: 100%` chain shrinks the bubble on narrow
  // viewports; the small aspect drift this introduces is masked by
  // `object-fit: cover` (image) / `contain` (video) on the inner element.
  const naturalAspect = naturalW && naturalH ? naturalW / naturalH : NaN;
  if (
    !naturalW ||
    !naturalH ||
    !Number.isFinite(naturalAspect) ||
    naturalAspect < STREAM_MEDIA_MIN_ASPECT ||
    naturalAspect > STREAM_MEDIA_MAX_ASPECT
  ) {
    return { width: toRem(STREAM_MEDIA_MAX_DIM), height: toRem(STREAM_MEDIA_MAX_DIM) };
  }
  if (naturalAspect >= 1) {
    const w = Math.min(STREAM_MEDIA_MAX_DIM, naturalW);
    return { width: toRem(w), height: toRem(w / naturalAspect) };
  }
  const h = Math.min(STREAM_MEDIA_MAX_DIM, naturalH);
  return { width: toRem(h * naturalAspect), height: toRem(h) };
}

// Shared chrome for image / video timeline bubbles: an aspect-preserving
// (up to 168px) preview box with uniformly-rounded R400 corners and a 1px
// pseudo-frame. Caller plugs in the actual media renderer as `children`.
// The sender nick is rendered ABOVE the media by the Stream layout's name
// header (like text messages), not overlaid on the image. `own` no longer
// affects rendering after the uniform-corner change — it survives only as
// a debug-log field (sender vs peer) for the media-measure diagnostics.
export function StreamMediaShell({ naturalW, naturalH, own, children }: StreamMediaShellProps) {
  const bubbleRef = useRef<HTMLDivElement>(null);
  const computedStyle = computeBoxStyle(naturalW, naturalH);

  logMedia('StreamMediaShell', {
    own,
    naturalW,
    naturalH,
    computedStyle: { ...computedStyle },
  });

  useMediaMeasureDebug(bubbleRef, [computedStyle.width, computedStyle.height]);

  return (
    <div ref={bubbleRef} className={StreamMediaBubble} style={computedStyle}>
      {children}
    </div>
  );
}
