import type { SoulConfig, UserConfig, ToolsConfig, InstallAction } from '../types.js';
import { FileConfigAdapter } from './file-adapter.js';

/** Supported top-level config sections for dotted-key access. */
export type ConfigSection = 'soul' | 'user' | 'tools';

/** A resolved view of all config sections, keyed by section name. */
export interface ResolvedConfig {
  soul: SoulConfig;
  user: UserConfig;
  tools: ToolsConfig;
}

/**
 * ConfigService interface — abstracts config read/write operations.
 * Currently backed by FileConfigAdapter (writes .md files from templates).
 * Designed for future swap to SqliteConfigAdapter or PostgresConfigAdapter.
 */
export interface ConfigService {
  readSoul(): Promise<SoulConfig>;
  readUser(): Promise<UserConfig>;
  readTools(): Promise<ToolsConfig>;

  writeSoul(config: SoulConfig): Promise<void>;
  writeUser(config: UserConfig): Promise<void>;
  writeTools(config: ToolsConfig): Promise<void>;

  syncFramework(action: InstallAction): Promise<void>;

  /**
   * Return the resolved (merged) config across all sections.
   */
  readAll(): Promise<ResolvedConfig>;

  /**
   * Read a single value by dotted key (e.g. "soul.agentName").
   * Returns undefined if the key doesn't exist.
   */
  getValue(dottedKey: string): Promise<unknown>;

  /**
   * Set a single value by dotted key (e.g. "soul.agentName") and persist.
   * Returns the previous value (or undefined).
   */
  setValue(dottedKey: string, value: string): Promise<unknown>;

  /**
   * Return the filesystem path for a given config section file.
   * When no section is provided, returns the mosaicHome directory.
   */
  getConfigPath(section?: ConfigSection): string;

  /**
   * Returns true if the mosaicHome directory exists and at least one
   * config file (SOUL.md, USER.md, TOOLS.md) is present.
   */
  isInitialized(): boolean;
}

export function createConfigService(mosaicHome: string, sourceDir: string): ConfigService {
  return new FileConfigAdapter(mosaicHome, sourceDir);
}
