import { readFileSync, writeFileSync, mkdirSync, chmodSync } from 'fs';
import { resolve } from 'path';
import { homedir } from 'os';

const AUTH_DIR = resolve(homedir(), '.config/flynn');
const AUTH_FILE = resolve(AUTH_DIR, 'auth.json');

export interface ZaiAuthInfo {
  /** Z.AI API key (used as Bearer token). */
  api_key: string;
  created_at: string;
}

interface AuthStore {
  // Keep other provider entries untyped to avoid cross-module coupling.
  github?: unknown;
  openai?: unknown;
  /** Preferred key for Z.AI credentials. */
  zai?: ZaiAuthInfo;
  /** Back-compat: older naming that matches the model provider id. */
  zhipuai?: ZaiAuthInfo;
}

function safeJsonParse<T>(raw: string): T | null {
  try {
    return JSON.parse(raw) as T;
  } catch {
    return null;
  }
}

function readAuthStore(): AuthStore {
  try {
    const raw = readFileSync(AUTH_FILE, 'utf-8');
    const parsed = safeJsonParse<AuthStore>(raw);
    return parsed ?? {};
  } catch {
    return {};
  }
}

function writeAuthStore(store: AuthStore): void {
  mkdirSync(AUTH_DIR, { recursive: true });
  writeFileSync(AUTH_FILE, JSON.stringify(store, null, 2) + '\n', 'utf-8');
  chmodSync(AUTH_FILE, 0o600);
}

export function loadStoredZaiAuth(): ZaiAuthInfo | null {
  const store = readAuthStore();
  return store.zai ?? store.zhipuai ?? null;
}

export function storeZaiAuth(apiKey: string): void {
  const trimmed = apiKey.trim();
  if (!trimmed) {
    throw new Error('Z.AI API key is empty');
  }
  const store = readAuthStore();
  store.zai = { api_key: trimmed, created_at: new Date().toISOString() };
  // Also write the provider-id alias for compatibility.
  store.zhipuai = store.zai;
  writeAuthStore(store);
}

export function clearZaiAuth(): void {
  const store = readAuthStore();
  delete store.zai;
  delete store.zhipuai;
  writeAuthStore(store);
}

/**
 * Get a Z.AI credential from any available source.
 * Priority: ZAI_API_KEY → ZHIPUAI_API_KEY → ZHIPUAI_AUTH_TOKEN → stored auth.json.
 */
export function getZaiApiKey(): string | null {
  const raw = process.env.ZAI_API_KEY
    ?? process.env.ZHIPUAI_API_KEY
    ?? process.env.ZHIPUAI_AUTH_TOKEN
    ?? loadStoredZaiAuth()?.api_key;

  if (!raw) {return null;}
  return raw.startsWith('Bearer ') ? raw.slice('Bearer '.length) : raw;
}
