/** Threads Graph API main post hard limit. */
export const THREADS_MAX_PUBLISH_CHARS = 500

/** Outreach / reply limit. */
export const THREADS_MAX_REPLY_CHARS = 1000

/** Viral engagement sweet spot on Threads feed. */
export const THREADS_VIRAL_SWEET_MIN = 80
export const THREADS_VIRAL_SWEET_MAX = 220

/** Engagement tends to drop beyond this length. */
export const THREADS_VIRAL_SOFT_WARN = 300

export type ThreadsPostLengthBand =
  | 'empty'
  | 'too_short'
  | 'sweet'
  | 'long'
  | 'over_soft'
  | 'over_hard'

export function threadsPostRuneLen(text?: string | null) {
  if (!text) return 0
  return [...text.trim()].length
}

export function threadsPostLengthBand(text: string): ThreadsPostLengthBand {
  const n = threadsPostRuneLen(text)
  if (n === 0) return 'empty'
  if (n < THREADS_VIRAL_SWEET_MIN) return 'too_short'
  if (n <= THREADS_VIRAL_SWEET_MAX) return 'sweet'
  if (n <= THREADS_VIRAL_SOFT_WARN) return 'long'
  if (n <= THREADS_MAX_PUBLISH_CHARS) return 'over_soft'
  return 'over_hard'
}

export function threadsPostLengthHint(text: string) {
  switch (threadsPostLengthBand(text)) {
    case 'too_short':
      return `偏短（爆款常見 ${THREADS_VIRAL_SWEET_MIN}～${THREADS_VIRAL_SWEET_MAX} 字）`
    case 'sweet':
      return `長度適中（爆款常見 ${THREADS_VIRAL_SWEET_MIN}～${THREADS_VIRAL_SWEET_MAX} 字）`
    case 'long':
      return `略長（超過 ${THREADS_VIRAL_SOFT_WARN} 字互動可能下降）`
    case 'over_soft':
      return `接近 Threads 主文上限 ${THREADS_MAX_PUBLISH_CHARS} 字`
    case 'over_hard':
      return `超過 Threads 上限 ${THREADS_MAX_PUBLISH_CHARS} 字，請縮短`
    default:
      return ''
  }
}

export function threadsPostLengthMeterClass(text: string) {
  switch (threadsPostLengthBand(text)) {
    case 'sweet':
      return 'text-success'
    case 'too_short':
    case 'long':
      return 'text-warning'
    case 'over_soft':
    case 'over_hard':
      return 'text-danger'
    default:
      return 'text-muted'
  }
}

export function threadsPostPublishBlocked(text: string) {
  return threadsPostRuneLen(text) > THREADS_MAX_PUBLISH_CHARS || threadsPostRuneLen(text) === 0
}