// Settings Scope Store — centralized resolution of per-project overrides.
// Provides scoped get/set: reads project-level override if exists, falls back to global.
// Single source of truth for which scope is active and how overrides cascade.

import { getSetting, setSetting } from './settings-store.svelte';

type Scope = 'global' | 'project';

interface ScopeOverride {
  key: string;
  globalValue: string | null;
  projectValue: string | null;
  effectiveValue: string | null;
  source: Scope;
}

let activeProjectId = $state<string | null>(null);
let overrideCache = $state<Map<string, ScopeOverride>>(new Map());

/** Set the active project for scoped settings resolution. */
export function setActiveProject(projectId: string | null) {
  activeProjectId = projectId;
  overrideCache = new Map();
}

/** Get the currently active project ID. */
export function getActiveProjectForSettings(): string | null {
  return activeProjectId;
}

/** Get a setting value with scope resolution.
 * If activeProjectId is set and a project-specific override exists, return that.
 * Otherwise return the global value. */
export async function scopedGet(key: string): Promise<string | null> {
  // Check cache first
  const cached = overrideCache.get(key);
  if (cached) return cached.effectiveValue;

  const globalValue = await getSetting(key);

  if (!activeProjectId) {
    overrideCache.set(key, { key, globalValue, projectValue: null, effectiveValue: globalValue, source: 'global' });
    return globalValue;
  }

  const projectKey = `project:${activeProjectId}:${key}`;
  const projectValue = await getSetting(projectKey);

  const effectiveValue = projectValue ?? globalValue;
  const source: Scope = projectValue !== null ? 'project' : 'global';

  overrideCache.set(key, { key, globalValue, projectValue, effectiveValue, source });
  return effectiveValue;
}

/** Set a setting value at the specified scope. */
export async function scopedSet(key: string, value: string, scope: Scope = 'global'): Promise<void> {
  if (scope === 'project' && activeProjectId) {
    const projectKey = `project:${activeProjectId}:${key}`;
    await setSetting(projectKey, value);
  } else {
    await setSetting(key, value);
  }
  // Invalidate cache for this key
  overrideCache.delete(key);
}

/** Remove a project-level override, reverting to global. */
export async function removeOverride(key: string): Promise<void> {
  if (!activeProjectId) return;
  const projectKey = `project:${activeProjectId}:${key}`;
  await setSetting(projectKey, '');
  overrideCache.delete(key);
}

/** Get the full override chain for a setting (for ScopeCascade display). */
export async function getOverrideChain(key: string): Promise<ScopeOverride> {
  const cached = overrideCache.get(key);
  if (cached) return cached;

  const globalValue = await getSetting(key);
  let projectValue: string | null = null;

  if (activeProjectId) {
    const projectKey = `project:${activeProjectId}:${key}`;
    projectValue = await getSetting(projectKey);
  }

  const effectiveValue = projectValue ?? globalValue;
  const source: Scope = projectValue !== null ? 'project' : 'global';
  const override: ScopeOverride = { key, globalValue, projectValue, effectiveValue, source };
  overrideCache.set(key, override);
  return override;
}

/** Check if a setting has a project-level override. */
export function hasProjectOverride(key: string): boolean {
  const cached = overrideCache.get(key);
  return cached?.source === 'project';
}

/** Clear the entire cache (call on project switch). */
export function invalidateSettingsCache() {
  overrideCache = new Map();
}

export type { Scope, ScopeOverride };
