/**
 * Tabata Programs — Data Access Layer
 * Central exports and helper functions for tabata programs
 */

import type { TabataProgram, TabataProgramId, TabataSession } from '../../types/program'
import type { Workout, Exercise } from '../../types/workout'
import { DEBUTANT_PROGRAM, DEBUTANT_SESSIONS } from './debutant'
import { INTERMEDIAIRE_PROGRAM, INTERMEDIAIRE_SESSIONS } from './intermediaire'
import { AVANCE_PROGRAM, AVANCE_SESSIONS } from './avance'
import { BUREAU_PROGRAM, BUREAU_SESSIONS } from './bureau'

// ─── Program Registry ──────────────────────────────────────────

const _PROGRAMS: Record<TabataProgramId, TabataProgram> = {
  debutant: DEBUTANT_PROGRAM,
  intermediaire: INTERMEDIAIRE_PROGRAM,
  avance: AVANCE_PROGRAM,
  bureau: BUREAU_PROGRAM,
}

// ─── Program Access ────────────────────────────────────────────

export function getTabataProgramById(id: TabataProgramId): TabataProgram | undefined {
  return _PROGRAMS[id]
}

export function getAllTabataPrograms(): TabataProgram[] {
  return Object.values(_PROGRAMS).filter(Boolean) as TabataProgram[]
}

export function getPremiumPrograms(): TabataProgram[] {
  return getAllTabataPrograms().filter(p => p.tier === 'premium')
}

// ─── Session Access ────────────────────────────────────────────

/** Get all sessions across all programs */
export function getAllTabataSessions(): TabataSession[] {
  return getAllTabataPrograms().flatMap(p => p.weeks.flatMap(w => w.sessions))
}

/** Find a session by ID across all programs */
export function getTabataSessionById(id: string): TabataSession | undefined {
  return getAllTabataSessions().find(s => s.id === id)
}

/** Get all sessions for a specific program */
export function getTabataSessionsByProgram(programId: TabataProgramId): TabataSession[] {
  const program = getTabataProgramById(programId)
  if (!program) return []
  return program.weeks.flatMap(w => w.sessions)
}

/** Get sessions for a specific week of a program */
export function getTabataSessionsByWeek(programId: TabataProgramId, weekNumber: number): TabataSession[] {
  const program = getTabataProgramById(programId)
  if (!program) return []
  const week = program.weeks.find(w => w.weekNumber === weekNumber)
  return week?.sessions ?? []
}

/** Determine which program a session belongs to */
export function getSessionProgramId(sessionId: string): TabataProgramId | undefined {
  for (const program of getAllTabataPrograms()) {
    const found = program.weeks.flatMap(w => w.sessions).find(s => s.id === sessionId)
    if (found) return program.id
  }
  return undefined
}

/** Check if a session ID belongs to the tabata system */
export function isTabataSession(sessionId: string): boolean {
  return sessionId.startsWith('deb-') || sessionId.startsWith('int-') ||
    sessionId.startsWith('avc-') || sessionId.startsWith('bur-')
}

// ─── Adapter: TabataSession → Workout ─────────────────────────

/**
 * Convert a TabataSession's current block to a Workout-compatible object
 * for use with the existing player and timer system.
 *
 * For multi-block sessions, pass blockIndex (default: 0).
 * The player will need to handle block progression separately.
 */
export function tabataSessionToWorkoutAdapter(
  session: TabataSession,
  blockIndex = 0,
): Workout {
  const block = session.blocks[blockIndex]
  if (!block) throw new Error(`Block ${blockIndex} not found in session ${session.id}`)

  const exercises: Exercise[] = []
  for (let i = 0; i < block.rounds; i++) {
    const exercise = i % 2 === 0 ? block.oddExercise : block.evenExercise
    exercises.push({
      name: exercise.name,
      duration: block.workTime,
    })
  }

  return {
    id: session.id,
    title: `${session.title} — Bloc ${blockIndex + 1}`,
    trainerId: 'tabata',
    category: 'full-body',
    level: 'Beginner',
    duration: Math.ceil(session.totalDuration / session.blocks.length) as Workout['duration'],
    calories: Math.ceil(session.calories / session.blocks.length),
    exercises,
    rounds: block.rounds,
    prepTime: blockIndex === 0 ? 10 : 60,
    workTime: block.workTime,
    restTime: block.restTime,
    equipment: session.equipment,
    musicVibe: 'chill',
  }
}

// ─── Re-exports ────────────────────────────────────────────────

export { DEBUTANT_PROGRAM, DEBUTANT_SESSIONS } from './debutant'
export { INTERMEDIAIRE_PROGRAM, INTERMEDIAIRE_SESSIONS } from './intermediaire'
export { AVANCE_PROGRAM, AVANCE_SESSIONS } from './avance'
export { BUREAU_PROGRAM, BUREAU_SESSIONS } from './bureau'
