/**
 * Workout View Controller — UI Rendering for Active/Resting screens
 *
 * Maps LiveWorkoutState into Fitbit SVG GUI element updates.
 * This is the "render" function for the main workout flow.
 *
 * In production: uses document.getElementById() + .text/.style.display
 * For the spike: type-level documentation of the mapping.
 */

import type { LiveWorkoutState } from '../state-model';
import type { UiUpdater, GuiElementId } from './types';

/**
 * Render the active workout screen.
 * Called on every dispatch() after state update.
 */
export function renderActiveWorkout(ui: UiUpdater, state: LiveWorkoutState): void {
  if (!state.plan) return;

  const exercise = state.plan.exercises[state.currentExerciseIndex];
  if (!exercise) return;

  const currentSet = exercise.sets[state.currentSetIndex];

  // Exercise header
  ui.setText('lbl-exercise-name' as GuiElementId, exercise.name);
  ui.setText('lbl-set-progress' as GuiElementId, `Set ${state.currentSetIndex + 1} / ${exercise.sets.length}`);

  // Target values from plan
  ui.setText('lbl-target-weight' as GuiElementId, formatWeight(currentSet.targetWeightKg));
  ui.setText('lbl-target-reps' as GuiElementId, currentSet.targetReps);
  ui.setText('lbl-target-rir' as GuiElementId, formatRir(currentSet.targetRir));

  // Actual values (user-adjustable)
  const actualWeight = currentSet.actualWeightKg ?? currentSet.targetWeightKg ?? 0;
  const actualReps = currentSet.actualReps ?? parseInt(currentSet.targetReps, 10) || 0;
  const actualRir = currentSet.actualRir ?? currentSet.targetRir ?? 2;

  ui.setText('lbl-actual-weight' as GuiElementId, `${actualWeight} kg`);
  ui.setText('lbl-actual-reps' as GuiElementId, `${actualReps}`);
  ui.setText('lbl-actual-rir' as GuiElementId, formatRir(actualRir));

  // Notes (if any)
  if (exercise.notes) {
    ui.setText('lbl-exercise-notes' as GuiElementId, exercise.notes);
    ui.setVisibility('lbl-exercise-notes' as GuiElementId, true);
  } else {
    ui.setVisibility('lbl-exercise-notes' as GuiElementId, false);
  }

  // Progress
  const totalSets = exercise.sets.length;
  const completedSets = exercise.sets.filter(
    (s) => s.completedAt !== null || s.skipped,
  ).length;
  ui.setProgress('lbl-set-progress' as GuiElementId, completedSets, totalSets);

  // Offline indicator
  ui.setVisibility('img-offline-indicator' as GuiElementId, state.isOffline);

  // Button states
  ui.setVisibility('btn-prev-exercise' as GuiElementId, state.currentExerciseIndex > 0);
  ui.setVisibility('btn-next-exercise' as GuiElementId, state.currentExerciseIndex < state.plan.exercises.length - 1);
}

/**
 * Render the resting screen.
 */
export function renderResting(ui: UiUpdater, state: LiveWorkoutState): void {
  ui.setText('lbl-rest-timer' as GuiElementId, state.restTimerDisplay || formatRestTimer(state.resting.remainingSec));

  // Show next exercise preview
  if (state.plan) {
    const exercise = state.plan.exercises[state.currentExerciseIndex];
    const nextSetIdx = state.currentSetIndex + 1;
    const nextLabel =
      nextSetIdx < exercise.sets.length
        ? `Next: ${exercise.name} Set ${nextSetIdx + 1}`
        : state.currentExerciseIndex + 1 < state.plan.exercises.length
          ? `Next: ${state.plan.exercises[state.currentExerciseIndex + 1].name}`
          : 'Last set! 💪';
    ui.setText('lbl-rest-next-exercise' as GuiElementId, nextLabel);
  }
}

// ─── Formatting helpers ──────────────────────────────────────────────

function formatWeight(kg: number | null): string {
  if (kg === null || kg === undefined) return '— kg';
  return `${kg} kg`;
}

function formatRir(rir: number | null): string {
  if (rir === null || rir === undefined) return 'RIR —';
  return `RIR ${rir}`;
}

export function formatRestTimer(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  return `${m}:${s.toString().padStart(2, '0')}`;
}

/**
 * Weight adjustment presets.
 * These are the delta values applied when user taps +/- buttons.
 */
export const WEIGHT_ADJUST_STEPS = {
  /** Default step: 2.5 kg (common plate increment) */
  DEFAULT: 2.5,
  /** Micro step: 1.25 kg */
  MICRO: 1.25,
  /** Big step: 5 kg */
  BIG: 5,
} as const;

export const REP_ADJUST_STEPS = {
  /** Default: ±1 rep */
  DEFAULT: 1,
} as const;
