import fs from 'node:fs';
import path from 'node:path';

const DATA_DIR = process.env.DATA_DIR ?? '/data';
const stateFile = path.join(DATA_DIR, 'hub-state.json');
const backupFile = stateFile + '.bak';
const tmpFile = stateFile + '.tmp';

let state: Record<string, any> = {};

export function loadState(): void {
  // Try main file first, fall back to backup if corrupted
  for (const file of [stateFile, backupFile]) {
    try {
      if (fs.existsSync(file)) {
        state = JSON.parse(fs.readFileSync(file, 'utf-8'));
        const keys = Object.keys(state);
        console.log(`[State] Loaded from ${path.basename(file)} (${keys.length} keys: ${keys.join(', ')})`);
        // Create backup on successful load from main file
        if (file === stateFile) {
          try { fs.copyFileSync(stateFile, backupFile); } catch {}
        }
        return;
      }
    } catch (e) {
      console.error(`[State] Failed to load ${path.basename(file)}:`, e);
    }
  }
  console.log('[State] No existing state found, starting fresh');
}

export function saveState(): void {
  try {
    fs.mkdirSync(path.dirname(stateFile), { recursive: true });
    // Atomic write: write to tmp file, then rename
    // rename() is atomic on POSIX filesystems, prevents corruption on crash
    fs.writeFileSync(tmpFile, JSON.stringify(state, null, 2));
    fs.renameSync(tmpFile, stateFile);
  } catch (e) {
    console.error('[State] Failed to save:', e);
  }
}

export function getState<T = any>(key: string, defaultValue?: T): T {
  return (state[key] as T) ?? (defaultValue as T);
}

export function setState(key: string, value: any): void {
  state[key] = value;
  saveState();
}

export function getFullState(): Record<string, any> {
  return { ...state };
}
