/**
 * §11 Inline-Medien: aus HTML / Übungsobjekt referenzierte exercise_media-IDs sammeln.
 */

const DATA_ATTR_RE = /data-shinkan-exercise-media\s*=\s*["']?(\d+)/gi

export const SHINKAN_EXERCISE_MEDIA_DRAG_MIME = 'application/x-shinkan-exercise-media'

/**
 * @param {string|null|undefined} html
 * @returns {Set<number>}
 */
export function collectInlineExerciseMediaIdsFromHtml(html) {
  const ids = new Set()
  if (!html || typeof html !== 'string') return ids
  let m
  const re = new RegExp(DATA_ATTR_RE.source, 'gi')
  while ((m = re.exec(html)) !== null) {
    const n = parseInt(m[1], 10)
    if (Number.isFinite(n) && n > 0) ids.add(n)
  }
  return ids
}

const EXERCISE_RTF_FIELDS = ['summary', 'goal', 'execution', 'preparation', 'trainer_notes']

/**
 * HTML-Schnipsel aus Übung + Varianten-Fließtext für Inline-Scan.
 * @param {object|null|undefined} exercise
 * @returns {string[]}
 */
export function gatherExerciseHtmlSlicesForInlineScan(exercise) {
  if (!exercise || typeof exercise !== 'object') return []
  const slices = []
  for (const f of EXERCISE_RTF_FIELDS) {
    const html = exercise[f]
    if (typeof html === 'string' && html.trim()) slices.push(html)
  }
  for (const v of exercise.variants || []) {
    const ec = v?.execution_changes
    if (typeof ec === 'string' && ec.trim()) slices.push(ec)
  }
  return slices
}

/**
 * Alle im Fließtext eingebetteten exercise_media-IDs (Übung + Varianten).
 * @param {object|null|undefined} exercise
 * @returns {Set<number>}
 */
export function collectInlineExerciseMediaIdsFromExercise(exercise) {
  const ids = new Set()
  for (const html of gatherExerciseHtmlSlicesForInlineScan(exercise)) {
    collectInlineExerciseMediaIdsFromHtml(html).forEach((id) => ids.add(id))
  }
  return ids
}

/**
 * @param {number} exerciseMediaId
 * @param {string} [caption]
 */
export function buildExerciseMediaDragPayload(exerciseMediaId, caption = '') {
  return JSON.stringify({
    exerciseMediaId: Number(exerciseMediaId),
    caption: typeof caption === 'string' ? caption : '',
  })
}

/**
 * @param {string} raw
 * @returns {{ exerciseMediaId: number, caption: string }|null}
 */
export function parseExerciseMediaDragPayload(raw) {
  if (!raw || typeof raw !== 'string') return null
  try {
    const o = JSON.parse(raw)
    const id = Number(o.exerciseMediaId)
    if (!Number.isFinite(id) || id < 1) return null
    const caption = typeof o.caption === 'string' ? o.caption : ''
    return { exerciseMediaId: id, caption }
  } catch {
    return null
  }
}
