// Interaction with DB restore (src/db/worker.js, handleImportDb): when a backup
// is restored, migration scripts in range run against the *temp* DB before its
// tables are copied into the live DB, and the schema_version table is NOT
// copied — the live DB keeps its current-version stamp. If it were copied, the
// next launch would see the backup's old stamp and re-run migrations against an
// already-adapted schema (e.g. a duplicate ALTER TABLE ADD COLUMN would fail
// and block the app behind the migration-failed screen). The first release that
// bumps schemaVersion past 1 must ship an end-to-end test restoring an
// older-version backup.
export const RELEASES = [
  {
    schemaVersion: 1,
    appVersion: '1.0.0',
    dbBreak: false,
    migrationScript: null,
  },
]

/**
 * Minimum tables a valid TrainUs DB must contain.
 */
export const REQUIRED_TABLES = ['schema_version', 'settings']

/**
 * Ordered migration scripts to bring a live DB from `fromVersion` up to `toVersion`.
 * Returns [{ schemaVersion, script }] for releases in (fromVersion, toVersion], ascending.
 * A release with `migrationScript: null` and `dbBreak: false` is a valid no-op migration
 * (only the schema_version row is stamped). Every schemaVersion bump must ship exactly
 * one RELEASES entry.
 * Throws if a release in range has `dbBreak: true` without a migration script.
 */
export function getMigrationScripts(fromVersion, toVersion) {
  const releasesInRange = RELEASES.filter(
    (r) => r.schemaVersion > fromVersion && r.schemaVersion <= toVersion,
  ).sort((a, b) => a.schemaVersion - b.schemaVersion)

  const blocked = releasesInRange.find((r) => r.dbBreak && !r.migrationScript)
  if (blocked) {
    throw new Error(`Missing migration script for breaking schema version ${blocked.schemaVersion}`)
  }

  return releasesInRange.map((r) => ({
    schemaVersion: r.schemaVersion,
    script: r.migrationScript,
  }))
}

/**
 * Check if two schema versions are compatible.
 * Returns { compatible, needsAdapt, scripts } where:
 * - compatible: true if migration path exists (or same version)
 * - needsAdapt: true if migration scripts need to run
 * - scripts: array of SQL migration scripts to run sequentially
 */
export function checkCompatibility(importedVersion, currentVersion) {
  if (importedVersion === currentVersion) {
    return { compatible: true, needsAdapt: false, scripts: [] }
  }

  // Determine direction: upgrading imported data to current schema
  const ascending = importedVersion < currentVersion
  const fromVersion = Math.min(importedVersion, currentVersion)
  const toVersion = Math.max(importedVersion, currentVersion)

  // Collect releases between fromVersion (exclusive) and toVersion (inclusive)
  const releasesInRange = RELEASES.filter(
    (r) => r.schemaVersion > fromVersion && r.schemaVersion <= toVersion,
  ).sort((a, b) => a.schemaVersion - b.schemaVersion)

  const hasBreak = releasesInRange.some((r) => r.dbBreak)

  if (!hasBreak) {
    // No breaking changes in the range — compatible without adaptation
    return { compatible: true, needsAdapt: false, scripts: [] }
  }

  // There are breaking changes — collect migration scripts
  const scriptsNeeded = ascending
    ? releasesInRange.filter((r) => r.dbBreak)
    : releasesInRange.filter((r) => r.dbBreak).reverse()

  const missingScript = scriptsNeeded.some((r) => !r.migrationScript)
  if (missingScript) {
    return { compatible: false, needsAdapt: true, scripts: [] }
  }

  return {
    compatible: true,
    needsAdapt: true,
    scripts: scriptsNeeded.map((r) => r.migrationScript),
  }
}
