/** Parsování `planning_run.solver_params` z GET /plan/current (run je celý JSON řádek). */

export type PlanMaskSlot = {
  allow_charge: boolean
  allow_discharge_export: boolean
  neg_sell_phase?: 'none' | 'prep' | 'tail' | null
  neg_sell_soc_target_wh?: number | null
}

export type PlanSolverSnapshot = {
  chargeAcquisitionKwh: number | null
  chargeAcquisitionCutoffAt: string | null
  masksByIso: Map<string, PlanMaskSlot>
  chargeMaskCount: number
  exportMaskCount: number
}

function recordBool(v: unknown): boolean {
  return v === true
}

function recordNumber(v: unknown): number | null {
  if (v == null) return null
  const n = Number(v)
  return Number.isFinite(n) ? n : null
}

function recordString(v: unknown): string | null {
  return typeof v === 'string' && v.length > 0 ? v : null
}

export function parsePlanSolverSnapshot(
  run: Record<string, unknown> | null | undefined,
): PlanSolverSnapshot | null {
  if (run == null) return null
  const raw = run.solver_params
  if (raw == null || typeof raw !== 'object') return null
  const sp = raw as Record<string, unknown>
  const inputs =
    sp.inputs != null && typeof sp.inputs === 'object'
      ? (sp.inputs as Record<string, unknown>)
      : null

  const masksByIso = new Map<string, PlanMaskSlot>()
  const masks = sp.masks
  if (Array.isArray(masks)) {
    for (const m of masks) {
      if (m == null || typeof m !== 'object') continue
      const row = m as Record<string, unknown>
      const slot = recordString(row.slot)
      if (slot == null) continue
      const phaseRaw = row.neg_sell_phase
      const phase =
        phaseRaw === 'prep' || phaseRaw === 'tail' || phaseRaw === 'none'
          ? phaseRaw
          : null
      masksByIso.set(slot, {
        allow_charge: recordBool(row.allow_charge),
        allow_discharge_export: recordBool(row.allow_discharge_export),
        neg_sell_phase: phase,
        neg_sell_soc_target_wh: recordNumber(row.neg_sell_soc_target_wh),
      })
    }
  }

  let chargeMaskCount = 0
  let exportMaskCount = 0
  for (const v of masksByIso.values()) {
    if (v.allow_charge) chargeMaskCount += 1
    if (v.allow_discharge_export) exportMaskCount += 1
  }

  return {
    chargeAcquisitionKwh: inputs
      ? recordNumber(inputs.charge_acquisition_buy_czk_kwh)
      : null,
    chargeAcquisitionCutoffAt: inputs
      ? recordString(inputs.charge_acquisition_cutoff_at)
      : null,
    masksByIso,
    chargeMaskCount,
    exportMaskCount,
  }
}

export function maskForInterval(
  snapshot: PlanSolverSnapshot | null,
  intervalStartIso: string,
): PlanMaskSlot | null {
  if (snapshot == null) return null
  return snapshot.masksByIso.get(intervalStartIso) ?? null
}
