/**
 * Hilfen für Trainingsplan-Ansicht, Coach-Modus und API-Payload für PUT /training-units/:id.
 */

export function sortedSections(unit) {
  const raw = unit?.sections
  if (!Array.isArray(raw)) return []
  return [...raw].sort((a, b) => (a.order_index ?? 0) - (b.order_index ?? 0))
}

export function sortedItems(sec) {
  const raw = sec?.items
  if (!Array.isArray(raw)) return []
  return [...raw].sort((a, b) => (a.order_index ?? 0) - (b.order_index ?? 0))
}

export function itemStableKey(it, secOrder, ix) {
  if (it && it.id != null) return String(it.id)
  return `${secOrder}-${it?.item_type || 'row'}-${ix}`
}

/** Flache Reihenfolge wie auf der Matte: alle Notizen und Übungen nacheinander. */
export function flattenPlanTimeline(unit) {
  const list = []
  sortedSections(unit).forEach((sec, si) => {
    const secOrder = sec.order_index ?? si
    sortedItems(sec).forEach((item, ii) => {
      list.push({
        si,
        ii,
        secOrder,
        flatIndex: list.length,
        sec,
        item,
      })
    })
  })
  return list
}

export function summarizeTimelineEntry({ item }) {
  if (!item) return ''
  if (item.item_type === 'note') {
    const t = String(item.note_body || '').trim()
    return t.length > 72 ? `${t.slice(0, 70)}…` : t || 'Notiz'
  }
  const title = item.exercise_title || (item.exercise_id ? `Übung #${item.exercise_id}` : 'Übung')
  const vn = item.exercise_variant_name ? ` · ${item.exercise_variant_name}` : ''
  return `${title}${vn}`
}

/** Payload für PUT (schließt bestehendes Unit mit optionalen Overrides pro Abschnitt-Item-ID ab). */
export function sectionsToPutPayload(unit, durationOverridesByItemId = {}) {
  return sortedSections(unit).map((sec, si) => ({
    order_index: sec.order_index ?? si,
    title: ((sec.title || '').trim() || 'Abschnitt'),
    guidance_notes: sec.guidance_notes?.trim() ? sec.guidance_notes.trim() : null,
    ...(sec.source_template_section_id != null
      ? { source_template_section_id: sec.source_template_section_id }
      : {}),
    items: sortedItems(sec)
      .map((it, ii) => {
        if (it.item_type === 'note') {
          return {
            item_type: 'note',
            order_index: it.order_index ?? ii,
            note_body: it.note_body ?? '',
          }
        }
        const eid = it.exercise_id
        if (eid === '' || eid == null || Number.isNaN(Number(eid))) {
          return null
        }
        const vid = it.exercise_variant_id
        let actual =
          durationOverridesByItemId[String(it.id)]?.actual_duration_min ??
          it.actual_duration_min
        if (actual === '' || actual === undefined) actual = null
        else actual = typeof actual === 'number' ? actual : parseInt(String(actual), 10)
        if (actual !== null && !Number.isFinite(actual)) actual = null

        return {
          item_type: 'exercise',
          order_index: it.order_index ?? ii,
          exercise_id: parseInt(String(eid), 10),
          exercise_variant_id:
            vid !== '' && vid != null && !Number.isNaN(Number(vid)) ? parseInt(String(vid), 10) : null,
          planned_duration_min: coalescePositiveInt(it.planned_duration_min),
          actual_duration_min: actual,
          notes: trimOrNull(it.notes),
          modifications: trimOrNull(it.modifications),
        }
      })
      .filter(Boolean),
  }))
}

function coalescePositiveInt(v) {
  if (v === '' || v === null || v === undefined) return null
  const n = parseInt(String(v), 10)
  return Number.isFinite(n) ? n : null
}

function trimOrNull(v) {
  const s = v != null ? String(v).trim() : ''
  return s ? s : null
}
