import { createShade } from '@shade/sdk';
import { readFileSync, writeFileSync } from 'fs';
import { loadConfig } from '../config.js';

/**
 * Export the current Shade state to a file.
 *
 * Usage: shade backup export <file> [--addresses bob,charlie]
 */
export async function backupExportCommand(
  file: string,
  options: { addresses?: string[] } = {},
): Promise<void> {
  const config = loadConfig();
  const shade = await createShade({
    prekeyServer: config.prekeyServer,
    storage: config.storage,
    address: config.address,
    autoReplenish: false,
  });

  try {
    // Prompt for passphrase via stdin (simple prompt, no hiding)
    process.stdout.write('Backup passphrase (min 12 chars): ');
    const passphrase = await readLine();

    const backupString = await shade.exportBackup(passphrase, options.addresses ?? []);
    writeFileSync(file, backupString);
    console.log(`\n\x1b[32m✓\x1b[0m Backup written to ${file}`);
    console.log(`  Size: ${backupString.length} bytes`);
    console.log(`  Keep this passphrase safe — it's the only way to restore.`);
  } finally {
    await shade.shutdown();
  }
}

/**
 * Restore a backup file into the current Shade storage.
 *
 * Usage: shade backup restore <file>
 */
export async function backupRestoreCommand(file: string): Promise<void> {
  const config = loadConfig();
  const backupString = readFileSync(file, 'utf-8').trim();

  const shade = await createShade({
    prekeyServer: config.prekeyServer,
    storage: config.storage,
    address: config.address,
    autoReplenish: false,
  });

  try {
    process.stdout.write('Passphrase: ');
    const passphrase = await readLine();

    await shade.importBackup(backupString, passphrase);
    console.log(`\n\x1b[32m✓\x1b[0m Backup restored`);
    console.log(`  Fingerprint: ${await shade.fingerprint}`);
  } finally {
    await shade.shutdown();
  }
}

async function readLine(): Promise<string> {
  const decoder = new TextDecoder();
  const buffer: string[] = [];
  for await (const chunk of Bun.stdin.stream()) {
    const text = decoder.decode(chunk as Uint8Array);
    const newlineIdx = text.indexOf('\n');
    if (newlineIdx >= 0) {
      buffer.push(text.slice(0, newlineIdx));
      break;
    }
    buffer.push(text);
  }
  return buffer.join('').trim();
}
