/** Gemeinsame Default-Filter für Übungslisten (Übersicht + Auswahlmodal). */
export const INITIAL_EXERCISE_LIST_FILTERS = {
  focus_area_ids: [],
  focus_rules: [],
  focus_only_without: false,
  style_direction_ids: [],
  style_direction_rules: [],
  training_type_ids: [],
  training_type_rules: [],
  target_group_ids: [],
  target_group_rules: [],
  skill_ids: [],
  skill_min_level: '',
  skill_max_level: '',
  visibility_any: [],
  visibility_exclude_any: [],
  visibility_rules: [],
  status_any: [],
  status_exclude_any: [],
  status_rules: [],
  exclude_without_focus: false,
  include_archived: false,
}

export const CATALOG_RULE_FIELD_KEYS = [
  'focus_rules',
  'style_direction_rules',
  'training_type_rules',
  'target_group_rules',
  'visibility_rules',
  'status_rules',
]

const PREFS_KEYS = Object.keys(INITIAL_EXERCISE_LIST_FILTERS)

export function newCatalogRuleKey(prefix = 'r') {
  if (typeof crypto !== 'undefined' && crypto.randomUUID) return `${prefix}-${crypto.randomUUID()}`
  return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
}

/** Einheitliche Regel-Zeile: { key, id, mode }. Legacy: focus_area_id. */
export function normalizeCatalogRule(r, i, prefix = 'r') {
  if (!r || typeof r !== 'object') return null
  const id = String(r.id ?? r.focus_area_id ?? '').trim()
  if (!id) return null
  const mode = r.mode === 'forbid' ? 'forbid' : 'require'
  return {
    key: r.key || newCatalogRuleKey(prefix),
    id,
    mode,
  }
}

export function splitMnCatalogRules(rules) {
  const inc = []
  const exc = []
  for (const r of rules || []) {
    const id = Number(r.id ?? r.focus_area_id)
    if (!Number.isFinite(id) || id < 1) continue
    if (r.mode === 'forbid') exc.push(id)
    else inc.push(id)
  }
  return {
    includeIds: [...new Set(inc)],
    excludeIds: [...new Set(exc)],
  }
}

/** Für visibility/status (einfaches Feld mit einem Wert pro Übung): + → OR (Liste), − → Ausschlussliste. */
export function splitScalarCatalogRules(rules) {
  const inc = []
  const exc = []
  for (const r of rules || []) {
    let id = String(r.id ?? '').trim().toLowerCase()
    if (!id) continue
    if (r.mode === 'forbid') exc.push(id)
    else inc.push(id)
  }
  return {
    includeVals: [...new Set(inc)],
    excludeVals: [...new Set(exc)],
  }
}

/**
 * Ruft aus dem Profilfeld exercise_list_prefs einen gültigen Filter-State ab.
 */
export function mergeExerciseListPrefsFromApi(raw) {
  const out = { ...INITIAL_EXERCISE_LIST_FILTERS }
  if (!raw || typeof raw !== 'object') return out

  for (const key of CATALOG_RULE_FIELD_KEYS) {
    if (!Array.isArray(raw[key])) continue
    out[key] = raw[key].map((r, i) => normalizeCatalogRule(r, i, key)).filter(Boolean)
  }

  if (raw.focus_only_without !== undefined) out.focus_only_without = !!raw.focus_only_without

  if (!out.visibility_rules.length) {
    const vr = []
    ;(raw.visibility_any || []).forEach((id, i) => {
      const n = normalizeCatalogRule({ id, mode: 'require', key: `lv-${i}` }, i, 'visibility_rules')
      if (n) vr.push(n)
    })
    ;(raw.visibility_exclude_any || []).forEach((id, i) => {
      const n = normalizeCatalogRule({ id, mode: 'forbid', key: `lve-${i}` }, i, 'visibility_rules')
      if (n) vr.push(n)
    })
    if (vr.length) out.visibility_rules = vr
  }

  if (!out.status_rules.length) {
    const sr = []
    ;(raw.status_any || []).forEach((id, i) => {
      const n = normalizeCatalogRule({ id, mode: 'require', key: `ls-${i}` }, i, 'status_rules')
      if (n) sr.push(n)
    })
    ;(raw.status_exclude_any || []).forEach((id, i) => {
      const n = normalizeCatalogRule({ id, mode: 'forbid', key: `lse-${i}` }, i, 'status_rules')
      if (n) sr.push(n)
    })
    if (sr.length) out.status_rules = sr
  }

  for (const k of PREFS_KEYS) {
    if (CATALOG_RULE_FIELD_KEYS.includes(k)) continue
    if (k === 'focus_only_without') continue
    if (raw[k] === undefined) continue
    if (
      k === 'visibility_any' ||
      k === 'visibility_exclude_any' ||
      k === 'status_any' ||
      k === 'status_exclude_any'
    ) {
      continue
    }
    if (k.endsWith('_ids') || k.endsWith('_any')) {
      if (Array.isArray(raw[k])) out[k] = raw[k].map(String)
      continue
    }
    if (k === 'exclude_without_focus' || k === 'include_archived') {
      out[k] = !!raw[k]
      continue
    }
    if (k === 'skill_min_level' || k === 'skill_max_level') {
      out[k] = raw[k] === '' || raw[k] == null ? '' : String(raw[k])
    }
  }
  return out
}

/** Nur von den Defaults abweichende Werte — kompaktes Profil-JSON. */
export function compactExerciseListPrefsPayload(filters) {
  const full = { ...INITIAL_EXERCISE_LIST_FILTERS, ...filters }
  const o = {}
  for (const k of PREFS_KEYS) {
    const v = full[k]
    const ini = INITIAL_EXERCISE_LIST_FILTERS[k]
    if (JSON.stringify(v) === JSON.stringify(ini)) continue
    o[k] = v
  }
  return o
}
