import { tryLoadConfig } from '../config.js';
import { existsSync } from 'fs';

export interface DoctorOptions {
  cwd?: string;
}

/**
 * Diagnose common setup issues.
 */
export async function doctorCommand(opts: DoctorOptions = {}): Promise<void> {
  let ok = true;
  console.log('\x1b[33mShade doctor\x1b[0m\n');

  // 1. Config loadable?
  const configResult = tryLoadConfig(opts.cwd);
  if (configResult.ok) {
    console.log('  \x1b[32m✓\x1b[0m Config loaded from .shaderc.json or env vars');
    const config = configResult.config;
    console.log(`    prekeyServer: ${config.prekeyServer}`);
    console.log(`    storage: ${config.storage}`);

    // 2. Storage path accessible?
    if (config.storage.startsWith('sqlite:')) {
      const path = config.storage.slice('sqlite:'.length);
      const dir = path.substring(0, path.lastIndexOf('/')) || '.';
      if (existsSync(dir)) {
        console.log(`  \x1b[32m✓\x1b[0m Storage directory exists: ${dir}`);
      } else {
        console.log(`  \x1b[31m✗\x1b[0m Storage directory missing: ${dir}`);
        ok = false;
      }
    }

    // 3. Prekey server reachable?
    try {
      const res = await fetch(`${config.prekeyServer}/health`, {
        signal: AbortSignal.timeout(5000),
      });
      if (res.ok) {
        console.log(`  \x1b[32m✓\x1b[0m Prekey server is reachable`);
      } else {
        console.log(`  \x1b[31m✗\x1b[0m Prekey server returned HTTP ${res.status}`);
        ok = false;
      }
    } catch (err) {
      console.log(`  \x1b[31m✗\x1b[0m Cannot reach prekey server: ${(err as Error).message}`);
      ok = false;
    }

    // 4. Observer token set?
    if (config.observerToken) {
      if (config.observerToken.length >= 16) {
        console.log(`  \x1b[32m✓\x1b[0m Observer token is set and long enough`);
      } else {
        console.log(`  \x1b[31m✗\x1b[0m Observer token must be at least 16 characters`);
        ok = false;
      }
    } else {
      console.log(`  \x1b[90m○\x1b[0m Observer token not set (dashboard disabled)`);
    }
  } else {
    console.log(`  \x1b[31m✗\x1b[0m ${configResult.error}`);
    ok = false;
  }

  console.log();
  if (ok) {
    console.log('\x1b[32mAll checks passed.\x1b[0m');
  } else {
    console.log('\x1b[31mSome checks failed. Fix the issues above and re-run.\x1b[0m');
    process.exitCode = 1;
  }
}
