// Per-row thread visualisation. Threading is `f(depth, activeAccent)`
// alone — no parent-child coordination, no central walker, no collapse.
// A row at depth N renders a stripe on its left edge in the active
// account's accent colour, faded by depth via a perceptually-smooth
// (smoothstep) opacity curve. Indent caps so phone-sized screens don't
// have their avatar column eaten; alpha keeps decreasing past the indent
// cap so depth stays legible even where the horizontal position plateaus.
//
// Reference: Reddit-colored-comments, HN threadlines, Discourse's nested
// view — modulo we tie the hue to the per-account accent variant
// (`AccountSummary.accentVariant`) instead of cycling a fixed palette.

import { withAlpha } from 'src/lib/color'
import { smoothstep } from 'src/lib/curves'
import { useTheme } from 'tamagui'

// 5 alpha samples for depths 1..5+. Past depth 5 the alpha sticks at
// FADE_FLOOR so the stripe never disappears entirely on extreme depth.
const FADE_LEVELS = 5
const FADE_PEAK = 0.95
const FADE_FLOOR = 0.15
export const FADE: readonly number[] = Array.from({ length: FADE_LEVELS }, (_, i) => {
  // i=0 → t=1 → smoothstep=1 → PEAK; i=N-1 → t=0 → smoothstep=0 → FLOOR.
  const t = 1 - i / (FADE_LEVELS - 1)
  return FADE_FLOOR + (FADE_PEAK - FADE_FLOOR) * smoothstep(t)
})

export const INDENT_CAP = 4
export const INDENT_STEP = 6
export const STRIPE_WIDTH = 5
export const STRIPE_GAP = 8
// Base left padding for depth 0 rows (no stripe). Kept as a named export
// so CommentItem can derive the available media width without duplicating
// the constant.
export const BASE_LEFT_PADDING = 15

const EMPTY: ReturnType<typeof composeStyle> = {}

type Style = {
  borderLeftWidth?: number
  borderLeftColor?: string
  paddingLeft?: number
}

function composeStyle(depth: number, accentHex: string): Style {
  if (depth <= 0) return {}
  const alpha = FADE[Math.min(depth, FADE_LEVELS) - 1]
  return {
    borderLeftWidth: STRIPE_WIDTH,
    borderLeftColor: withAlpha(accentHex, alpha),
    paddingLeft: STRIPE_GAP + Math.min(depth, INDENT_CAP) * INDENT_STEP,
  }
}

export function useThreadRowStyle(depth: number): Style {
  const theme = useTheme()
  if (depth <= 0) return EMPTY
  return composeStyle(depth, theme.accent.val as string)
}

// Pure variant for tests and any caller that already has the accent hex
// in hand (avoids the React hook constraint inside test runners).
export function threadRowStyleFor(depth: number, accentHex: string): Style {
  return composeStyle(depth, accentHex)
}

// Resolved left padding the row will actually render with. Callers need
// this to compute the available width for inline media: stripe takes its
// own pixels, paddingLeft sets where content starts. Mirrors composeStyle
// so the two never drift.
export function resolvedLeftInset(depth: number): number {
  if (depth <= 0) return BASE_LEFT_PADDING
  return STRIPE_GAP + Math.min(depth, INDENT_CAP) * INDENT_STEP
}
