import { keyframes, style } from '@vanilla-extract/css';
import { color, config, toRem } from 'folds';

// Dawn voice-note bubble — identical on native and web. The sender avatar sits
// OUTSIDE the bubble (bare, no background). Both own and other have a filled
// bubble with visible edges; the difference is the FILL TONE: others get a
// light subtle fill (SurfaceVariant.ContainerHover #21232b), own gets the
// darker fill of the composer / input form (Surface.Container #0d0e11 — the
// `${ChatComposer} .${Editor}` override in RoomView.css.ts, NOT the lighter
// SurfaceVariant). Same 1px edge on both. See docs/plans/voice_messages.md §5.

const fadeIn = keyframes({
  from: { opacity: 0, transform: 'translateY(3px)' },
  to: { opacity: 1, transform: 'translateY(0)' },
});

export const Row = style({
  display: 'flex',
  alignItems: 'center',
  gap: config.space.S300,
  width: '100%',
  boxSizing: 'border-box',
  animation: `${fadeIn} 180ms ease`,
});

// Own voice note with the avatar shown: the avatar sits to the RIGHT of the
// bubble and the bubble packs to the right edge. row-reverse flips the
// avatar→bubble order so the JSX order stays unchanged. Applied ONLY where
// VoiceContent still draws its avatar — the card previews (pin menu, message
// search). The timeline (bubble + channel) and the thread drawer all pass
// `hideAvatar`, so this never engages there.
export const RowOwn = style({
  flexDirection: 'row-reverse',
});

// Bare avatar — fixed 40px, no background box of its own (the avatar image /
// fallback fills it). Strip any container fill folds might apply.
export const AvatarSlot = style({
  flexShrink: 0,
  width: toRem(40),
  height: toRem(40),
  backgroundColor: 'transparent',
});

export const Bubble = style({
  display: 'flex',
  alignItems: 'center',
  gap: config.space.S300,
  flexGrow: 1,
  // Target width via flex-basis (so the waveform has comfortable room in the
  // shrink-wrapped 1:1 bubble chat), but `minWidth: 0` lets it shrink below that
  // on narrow panes/mobile — a hard floor here overflowed the row and got
  // clipped by the panel's overflow:hidden. Compact on native, a bit wider on
  // web (≥600px) where there's room.
  flexBasis: toRem(232),
  minWidth: 0,
  maxWidth: toRem(331),
  '@media': {
    'screen and (min-width: 600px)': {
      flexBasis: toRem(280),
      maxWidth: toRem(400),
    },
  },
  // Fixed height so own and other are pixel-identical regardless of fill.
  height: toRem(56),
  boxSizing: 'border-box',
  padding: `0 ${config.space.S400}`,
  color: color.SurfaceVariant.OnContainer,
  borderRadius: config.radii.R400,
  // Others (default): a light subtle fill with a visible 1px edge — the
  // "Владислав" look. Own overrides the fill to the darker composer tone below.
  backgroundColor: color.SurfaceVariant.ContainerHover,
  border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`,
});

// Own messages — the exact composer / input-form fill (Surface.Container,
// #0d0e11), darker than the peer fill; same edge.
export const BubbleOwn = style({
  backgroundColor: color.Surface.Container,
});

const playPulse = keyframes({
  '0%': { boxShadow: `0 0 0 0 ${color.Primary.Main}` },
  '70%': { boxShadow: `0 0 0 ${toRem(6)} rgba(0,0,0,0)` },
  '100%': { boxShadow: `0 0 0 0 rgba(0,0,0,0)` },
});

export const PlayButton = style({
  flexShrink: 0,
  width: toRem(40),
  height: toRem(40),
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  borderRadius: config.radii.Pill,
  border: 'none',
  padding: 0,
  cursor: 'pointer',
  backgroundColor: color.Primary.Main,
  color: color.Primary.OnMain,
  transition: 'transform 120ms ease, background-color 120ms ease',
  selectors: {
    '&:hover': { backgroundColor: color.Primary.MainHover, transform: 'scale(1.06)' },
    '&:active': { transform: 'scale(0.92)' },
    '&:disabled': { cursor: 'default', opacity: 0.6 },
  },
});

export const PlayButtonPlaying = style({
  animation: `${playPulse} 1.6s ease-out infinite`,
});

export const Waveform = style({
  position: 'relative',
  flexGrow: 1,
  minWidth: 0,
  display: 'flex',
  alignItems: 'center',
  gap: toRem(2),
  height: toRem(32),
  cursor: 'pointer',
  // Guarantee the react-range thumb can never paint past the track edge toward
  // the time readout (it's a 1px transparent overhang at most, but contain it).
  overflow: 'hidden',
});

const barGrow = keyframes({
  from: { transform: 'scaleY(0.25)' },
  to: { transform: 'scaleY(1)' },
});

export const WaveBar = style({
  flex: '1 1 0',
  minWidth: toRem(2),
  minHeight: toRem(3),
  borderRadius: toRem(2),
  transformOrigin: 'center',
  animation: `${barGrow} 220ms ease`,
  transition: 'background-color 120ms linear, transform 120ms ease',
});

export const WaveBarPlayed = style({ backgroundColor: color.Primary.Main });
export const WaveBarRest = style({ backgroundColor: color.SurfaceVariant.ContainerLine });

export const WaveThumb = style({
  width: toRem(2),
  height: '100%',
  backgroundColor: 'transparent',
  outline: 'none',
});

export const ProgressTrack = style({
  position: 'relative',
  flexGrow: 1,
  height: toRem(4),
  borderRadius: config.radii.Pill,
  backgroundColor: color.SurfaceVariant.ContainerLine,
  cursor: 'pointer',
});

export const ProgressFill = style({
  position: 'absolute',
  left: 0,
  top: 0,
  height: '100%',
  borderRadius: config.radii.Pill,
  backgroundColor: color.Primary.Main,
  transition: 'width 120ms linear',
});

export const Time = style({
  flexShrink: 0,
  minWidth: toRem(40),
  textAlign: 'right',
  fontVariantNumeric: 'tabular-nums',
});
