/**
 * Composable for managing shared connector theme.
 * Handles theme persistence and application.
 */
import { ref, type Ref } from '@/entrypoints/shared/reactivity';

/** Available theme identifiers */
export type AgentThemeId =
  | 'warm-editorial'
  | 'blueprint-architect'
  | 'zen-journal'
  | 'neo-pop'
  | 'dark-console'
  | 'swiss-grid';

/** Storage key for persisting theme preference */
const STORAGE_KEY_THEME = 'agentTheme';

/** Default theme when none is set */
const DEFAULT_THEME: AgentThemeId = 'warm-editorial';

/** Valid theme IDs for validation */
const VALID_THEMES: AgentThemeId[] = [
  'warm-editorial',
  'blueprint-architect',
  'zen-journal',
  'neo-pop',
  'dark-console',
  'swiss-grid',
];

/** Theme display names for UI */
export const THEME_LABELS: Record<AgentThemeId, string> = {
  'warm-editorial': 'Editorial',
  'blueprint-architect': 'Blueprint',
  'zen-journal': 'Zen',
  'neo-pop': 'Neo-Pop',
  'dark-console': 'Console',
  'swiss-grid': 'Swiss',
};

export interface UseAgentTheme {
  /** Current theme ID */
  theme: Ref<AgentThemeId>;
  /** Whether theme has been loaded from storage */
  ready: Ref<boolean>;
  /** Set and persist a new theme */
  setTheme: (id: AgentThemeId) => Promise<void>;
  /** Load theme from storage (call on mount) */
  initTheme: () => Promise<void>;
  /** Apply theme to a DOM element */
  applyTo: (el: HTMLElement) => void;
  /** Get the preloaded theme from document (set by main.ts) */
  getPreloadedTheme: () => AgentThemeId;
}

/**
 * Check if a string is a valid theme ID
 */
function isValidTheme(value: unknown): value is AgentThemeId {
  return typeof value === 'string' && VALID_THEMES.includes(value as AgentThemeId);
}

/**
 * Get theme from document element (preloaded by main.ts)
 */
function getThemeFromDocument(): AgentThemeId {
  const value = document.documentElement.dataset.agentTheme;
  return isValidTheme(value) ? value : DEFAULT_THEME;
}

/**
 * Composable for managing connector theme
 */
export function useAgentTheme(): UseAgentTheme {
  // Initialize with preloaded theme (or default)
  const theme = ref<AgentThemeId>(getThemeFromDocument());
  const ready = ref(false);

  /**
   * Load theme from chrome.storage.local
   */
  async function initTheme(): Promise<void> {
    try {
      const result = await chrome.storage.local.get(STORAGE_KEY_THEME);
      const stored = result[STORAGE_KEY_THEME];

      if (isValidTheme(stored)) {
        theme.value = stored;
      } else {
        // Use preloaded or default
        theme.value = getThemeFromDocument();
      }
    } catch (error) {
      console.error('[useAgentTheme] Failed to load theme:', error);
      theme.value = getThemeFromDocument();
    } finally {
      ready.value = true;
    }
  }

  /**
   * Set and persist a new theme
   */
  async function setTheme(id: AgentThemeId): Promise<void> {
    if (!isValidTheme(id)) {
      console.warn('[useAgentTheme] Invalid theme ID:', id);
      return;
    }

    // Update immediately for responsive UI
    theme.value = id;

    // Also update document element for consistency
    document.documentElement.dataset.agentTheme = id;

    // Persist to storage
    try {
      await chrome.storage.local.set({ [STORAGE_KEY_THEME]: id });
    } catch (error) {
      console.error('[useAgentTheme] Failed to save theme:', error);
    }
  }

  /**
   * Apply theme to a DOM element
   */
  function applyTo(el: HTMLElement): void {
    el.dataset.agentTheme = theme.value;
  }

  /**
   * Get the preloaded theme from document
   */
  function getPreloadedTheme(): AgentThemeId {
    return getThemeFromDocument();
  }

  return {
    theme,
    ready,
    setTheme,
    initTheme,
    applyTo,
    getPreloadedTheme,
  };
}

/**
 * Preload theme before UI mounts (call in main.ts).
 * This prevents theme flashing on page load.
 */
export async function preloadAgentTheme(): Promise<AgentThemeId> {
  let themeId: AgentThemeId = DEFAULT_THEME;

  try {
    const result = await chrome.storage.local.get(STORAGE_KEY_THEME);
    const stored = result[STORAGE_KEY_THEME];

    if (isValidTheme(stored)) {
      themeId = stored;
    }
  } catch (error) {
    console.error('[preloadAgentTheme] Failed to load theme:', error);
  }

  // Set on document element for immediate application
  document.documentElement.dataset.agentTheme = themeId;

  return themeId;
}
