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 AnthropicAuthInfo {
  /** Anthropic API key. */
  api_key?: string;
  /** Anthropic auth token (OAuth/token mode). */
  auth_token?: string;
  created_at: string;
}

interface AuthStore {
  anthropic?: AnthropicAuthInfo;
  [key: string]: unknown;
}

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 loadStoredAnthropicAuth(): AnthropicAuthInfo | null {
  const store = readAuthStore();
  return store.anthropic ?? null;
}

export function storeAnthropicAuth(apiKey: string): void {
  const trimmed = apiKey.trim();
  if (!trimmed) {
    throw new Error('Anthropic API key is empty');
  }
  const store = readAuthStore();
  store.anthropic = { ...store.anthropic, api_key: trimmed, created_at: new Date().toISOString() };
  writeAuthStore(store);
}

export function loadStoredAnthropicAuthToken(): string | null {
  return loadStoredAnthropicAuth()?.auth_token ?? null;
}

export function storeAnthropicAuthToken(token: string): void {
  const trimmed = token.trim();
  if (!trimmed) {
    throw new Error('Anthropic auth token is empty');
  }
  const store = readAuthStore();
  store.anthropic = { ...store.anthropic, auth_token: trimmed, created_at: new Date().toISOString() };
  writeAuthStore(store);
}

export function clearAnthropicAuth(): void {
  const store = readAuthStore();
  delete store.anthropic;
  writeAuthStore(store);
}

export function clearAnthropicAuthToken(): void {
  const store = readAuthStore();
  if (!store.anthropic) {
    writeAuthStore(store);
    return;
  }
  delete store.anthropic.auth_token;
  if (!store.anthropic.api_key && !store.anthropic.auth_token) {
    delete store.anthropic;
  }
  writeAuthStore(store);
}

/**
 * Get an Anthropic API key from any available source.
 * Priority: ANTHROPIC_API_KEY → stored auth.json.
 */
export function getAnthropicApiKey(): string | null {
  return process.env.ANTHROPIC_API_KEY
    ?? loadStoredAnthropicAuth()?.api_key
    ?? null;
}

/**
 * Get an Anthropic auth token from any available source.
 * Priority: ANTHROPIC_AUTH_TOKEN → stored auth.json.
 */
export function getAnthropicAuthToken(): string | null {
  return process.env.ANTHROPIC_AUTH_TOKEN
    ?? loadStoredAnthropicAuth()?.auth_token
    ?? null;
}
