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

// ── Card root ────────────────────────────────────────────────────
//
// Establishes the positioning context for the floating top-right
// 3-dot actions trigger. The card content (hero / info / alerts)
// sits in normal flow; the trigger is absolute-positioned over it.
export const CardRoot = style({
  position: 'relative',
});

// 3-dot button anchor — top-right of the card. `right: 0` lines it
// up flush with the card content's right edge (the panel padding
// is supplied by the host, so we don't add inset here).
export const CardActionsAnchor = style({
  position: 'absolute',
  top: 0,
  right: 0,
  zIndex: 1,
});

// ── Hero ─────────────────────────────────────────────────────────

export const HeroRoot = style({
  width: '100%',
  paddingTop: toRem(8),
});

// 96px round avatar wrapper. Uses `position: relative` so the
// online-dot can sit inset at bottom-right with a ring matching the
// surrounding background. Folds' `Avatar` is overridden globally to
// be circular, so we just size the wrapper and let the inner avatar
// fill it.
export const HeroAvatar = style({
  position: 'relative',
  display: 'inline-flex',
  width: toRem(96),
  height: toRem(96),
  borderRadius: '50%',
  flexShrink: 0,
  // Hairline ring sits on top of the gradient so we get the same
  // «inset border» rhythm as the chat-list rows in the design bundle.
  boxShadow: `0 0 0 ${config.borderWidth.B600} ${color.Background.Container}`,
});

// Linear gradient is set via inline style (so `colorMXID` can drive
// the base hue). This rule just makes the fallback span fill the
// avatar circle and centre its initial.
export const HeroAvatarFallback = style({
  width: '100%',
  height: '100%',
  borderRadius: '50%',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  color: '#fff',
  fontWeight: 600,
  fontSize: toRem(36),
  letterSpacing: '0.5px',
  textTransform: 'uppercase',
});

// Online indicator dot — green pill inset bottom-right of the
// avatar with a ring matching the parent background so it punches
// out against the avatar circle, mirroring the design bundle's
// `.online` glyph.
export const HeroOnlineDot = style({
  position: 'absolute',
  right: toRem(2),
  bottom: toRem(2),
  width: toRem(16),
  height: toRem(16),
  borderRadius: '50%',
  backgroundColor: color.Success.Main,
  boxShadow: `0 0 0 ${toRem(3)} ${color.Background.Container}`,
});

// Reset native button chrome for the tap-to-zoom avatar wrapper.
export const HeroAvatarButton = style({
  display: 'inline-flex',
  background: 'transparent',
  border: 'none',
  padding: 0,
  margin: 0,
  cursor: 'pointer',
});

// Desktop side-pane expanded avatar. Clicking the small hero avatar
// in the right-side profile pane flips this on: the wrapper
// stretches to the card width, squares up via `aspect-ratio` so the
// server-side 1:1 avatar shows full-bleed without cropping, and the
// rest of the card stays in flow below. Replaces the legacy full-pane
// avatar swap which hid the name / presence / info rows entirely.
//
// `&&` self-doubled selector + `!important` for `border-radius` is
// the override pattern for the global avatar-circle force in
// `components/user-avatar/UserAvatar.css.ts:23-25`, which uses
// `*:has(> .UserAvatar) { border-radius: 50% !important }` to round
// every avatar parent. A single-class override + `!important` would
// be source-order dependent (both rules carry `!important`, so the
// cascade falls to specificity). `&&` emits
// `.HeroAvatarExpanded.HeroAvatarExpanded` which doubles class
// specificity and beats the single-class selector inside the
// global `:has()`, so we win regardless of which CSS module the
// bundler emits first.
export const HeroAvatarExpanded = style({
  width: '100%',
  height: 'auto',
  aspectRatio: '1 / 1',
  boxShadow: 'none',
  selectors: {
    '&&': {
      borderRadius: `${toRem(16)} !important`,
    },
  },
});

export const HeroAvatarButtonExpanded = style({
  display: 'flex',
  width: '100%',
});

export const HeroIdentity = style({
  width: '100%',
});

export const HeroPresence = style({
  width: '100%',
  justifyContent: 'center',
});

// Coloured «онлайн» tag — mirrors the chat header's `OnlineTag`
// style so the two surfaces use identical typography for the same
// signal. Dropping the green dot prefix here is intentional: the
// avatar already carries the green online indicator, so a second
// dot would just be visual noise.
export const HeroOnlineTag = style({
  color: color.Success.Main,
  flexShrink: 0,
  whiteSpace: 'nowrap',
});

export const HeroBullet = style({
  color: color.Surface.ContainerLine,
});

export const HeroE2ee = style({
  display: 'inline-flex',
  alignItems: 'center',
  gap: toRem(4),
  color: color.Success.Main,
});

// Quiet «last activity» dot prefix used only on offline / idle
// presence labels. Online state has no dot here — the avatar's own
// green indicator serves that role.
export const PresenceDot = style({
  width: toRem(8),
  height: toRem(8),
  borderRadius: '50%',
  backgroundColor: color.Surface.ContainerLine,
  flexShrink: 0,
});

// ── Info section / rows (Fleet-style attribute table) ────────────

export const InfoSection = style({
  display: 'flex',
  flexDirection: 'column',
  gap: toRem(2),
  paddingTop: toRem(8),
  paddingBottom: toRem(8),
  borderTop: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
  borderBottom: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
});

export const InfoRow = style({
  display: 'flex',
  alignItems: 'center',
  gap: toRem(12),
  minHeight: toRem(32),
  padding: `${toRem(4)} ${toRem(2)}`,
});

// Fixed-width monospace label column. The `letter-spacing` and
// uppercase mirror Fleet's panel-attribute look.
export const InfoRowLabel = style({
  flexShrink: 0,
  width: toRem(72),
  fontFamily: 'ui-monospace, "JetBrains Mono", monospace',
  fontSize: toRem(11),
  letterSpacing: '0.06em',
  textTransform: 'uppercase',
  color: color.Surface.OnContainer,
  opacity: 0.55,
});

export const InfoRowValue = style({
  flex: 1,
  minWidth: 0,
  fontSize: toRem(13),
  color: color.Surface.OnContainer,
  whiteSpace: 'nowrap',
  overflow: 'hidden',
  textOverflow: 'ellipsis',
});

// Right-side affordance — copy / open / chevron-menu trigger. Looks
// like a tiny ghost icon button: transparent, hover-tints in the
// «hover surface» token, never grows past the row's intrinsic
// height.
export const InfoRowTrailing = style({
  flexShrink: 0,
  display: 'inline-flex',
  alignItems: 'center',
});

export const InfoRowAction = style({
  display: 'inline-flex',
  alignItems: 'center',
  justifyContent: 'center',
  width: toRem(24),
  height: toRem(24),
  borderRadius: toRem(6),
  background: 'transparent',
  border: 'none',
  color: color.Surface.OnContainer,
  cursor: 'pointer',
  opacity: 0.7,
  selectors: {
    '&:hover': {
      opacity: 1,
      background: color.SurfaceVariant.Container,
    },
    '&:disabled': {
      opacity: 0.3,
      cursor: 'default',
    },
    '&[aria-pressed="true"]': {
      opacity: 1,
      background: color.SurfaceVariant.Container,
    },
  },
});

// Variants used inside `InfoRowValue` — accent for creators (star
// badge), mixed (label + faint mono pl number side by side), mono
// (just the pl-N tag).
export const InfoRowAccent = style({
  display: 'inline-flex',
  alignItems: 'center',
  gap: toRem(6),
  color: color.Warning.Main,
  fontWeight: 600,
});

export const InfoRowMixed = style({
  display: 'inline-flex',
  alignItems: 'center',
  gap: toRem(8),
});

