import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import * as crypto from 'crypto';

const HOME = os.homedir();
export const CONFIG_DIR = path.join(HOME, '.config', 'ffctk');
export const CACHE_DIR = path.join(HOME, '.cache', 'ffctk');
export const CREDENTIALS_PATH = path.join(CONFIG_DIR, 'credentials');
export const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
export const DEVICE_ID_PATH = path.join(CONFIG_DIR, 'device_id');
export const OFFSETS_PATH = path.join(CACHE_DIR, 'offsets.json');
export const QUEUE_DB_PATH = path.join(CACHE_DIR, 'queue.db');
export const PRICING_PATH = path.join(CACHE_DIR, 'pricing.json');
export const LOG_PATH = path.join(CACHE_DIR, 'ffctk.log');

export interface AgentConfig {
  apiBase: string;
  batchSize: number;
  batchIntervalMs: number;
  logLevel: 'debug' | 'info' | 'warn' | 'error';
}

const DEFAULT_CONFIG: AgentConfig = {
  apiBase: process.env.FFCTK_API_BASE || 'https://ffai.faradayfuture.com',
  batchSize: 500,
  batchIntervalMs: 30_000,
  logLevel: 'info',
};

export function ensureDirs() {
  fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
  fs.mkdirSync(CACHE_DIR, { recursive: true, mode: 0o700 });
}

export function loadConfig(): AgentConfig {
  ensureDirs();
  if (!fs.existsSync(CONFIG_PATH)) return DEFAULT_CONFIG;
  try {
    return { ...DEFAULT_CONFIG, ...JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8')) };
  } catch {
    return DEFAULT_CONFIG;
  }
}

export function saveConfig(c: Partial<AgentConfig>) {
  ensureDirs();
  fs.writeFileSync(CONFIG_PATH, JSON.stringify({ ...loadConfig(), ...c }, null, 2), { mode: 0o600 });
}

export function loadToken(): string | null {
  if (!fs.existsSync(CREDENTIALS_PATH)) return null;
  return fs.readFileSync(CREDENTIALS_PATH, 'utf8').trim() || null;
}

export function saveToken(token: string) {
  ensureDirs();
  fs.writeFileSync(CREDENTIALS_PATH, token, { mode: 0o600 });
}

export function clearToken() {
  if (fs.existsSync(CREDENTIALS_PATH)) fs.unlinkSync(CREDENTIALS_PATH);
}

export function getOrCreateDeviceId(): string {
  ensureDirs();
  if (fs.existsSync(DEVICE_ID_PATH)) {
    const id = fs.readFileSync(DEVICE_ID_PATH, 'utf8').trim();
    if (id) return id;
  }
  const id = crypto.randomUUID();
  fs.writeFileSync(DEVICE_ID_PATH, id, { mode: 0o600 });
  return id;
}

export function getOsPlatform(): 'LINUX' | 'DARWIN' | 'WINDOWS' {
  const p = os.platform();
  if (p === 'darwin') return 'DARWIN';
  if (p === 'win32') return 'WINDOWS';
  return 'LINUX';
}

export function getAgentVersion(): string {
  return (process.env.FFCTK_VERSION || '0.1.0').slice(0, 32);
}
