/**
 * Filesystem-based TokenProvider.
 * Stores tokens in ~/.effigenix/config.json with file permissions 600.
 */

import fs from 'node:fs/promises';
import path from 'node:path';
import os from 'node:os';
import type { TokenProvider } from '@effigenix/api-client';

interface StoredAuth {
  accessToken: string;
  refreshToken: string;
  expiresAt: string;
  username?: string;
}

interface StoredConfig {
  apiBaseUrl?: string;
  auth?: StoredAuth;
}

const CONFIG_DIR = path.join(os.homedir(), '.effigenix');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');

async function loadConfig(): Promise<StoredConfig> {
  try {
    const raw = await fs.readFile(CONFIG_FILE, 'utf-8');
    return JSON.parse(raw) as StoredConfig;
  } catch {
    return {};
  }
}

async function saveConfig(config: StoredConfig): Promise<void> {
  await fs.mkdir(CONFIG_DIR, { recursive: true });
  await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
}

export const tokenStorage: TokenProvider = {
  async getAccessToken(): Promise<string | null> {
    const config = await loadConfig();
    if (!config.auth) return null;

    // Proaktiver Refresh: wenn weniger als 5 Minuten bis Ablauf
    const expiresAt = new Date(config.auth.expiresAt).getTime();
    const timeUntilExpiry = expiresAt - Date.now();
    if (timeUntilExpiry < 5 * 60 * 1000) {
      // Token bald abgelaufen – Aufrufer (RefreshInterceptor) übernimmt Refresh
      return null;
    }

    return config.auth.accessToken;
  },

  async getRefreshToken(): Promise<string | null> {
    const config = await loadConfig();
    return config.auth?.refreshToken ?? null;
  },

  async saveTokens(accessToken: string, refreshToken: string, expiresAt: string): Promise<void> {
    const config = await loadConfig();
    const existing = config.auth;
    config.auth = {
      accessToken,
      refreshToken,
      expiresAt,
      ...(existing?.username !== undefined ? { username: existing.username } : {}),
    };
    await saveConfig(config);
  },

  async clearTokens(): Promise<void> {
    const config = await loadConfig();
    delete config.auth;
    await saveConfig(config);
  },
};

export async function getStoredUsername(): Promise<string | undefined> {
  const config = await loadConfig();
  return config.auth?.username;
}

export async function saveUsername(username: string): Promise<void> {
  const config = await loadConfig();
  if (config.auth) {
    config.auth.username = username;
    await saveConfig(config);
  }
}

export async function getStoredApiBaseUrl(): Promise<string | undefined> {
  const config = await loadConfig();
  return config.apiBaseUrl;
}

export async function saveApiBaseUrl(url: string): Promise<void> {
  const config = await loadConfig();
  config.apiBaseUrl = url;
  await saveConfig(config);
}
