/**
 * Composable for managing site configuration
 *
 * This composable provides methods for reading and updating site configuration
 * values stored in the database. Configuration values are cached in the client
 * to reduce unnecessary API calls.
 */
import { useApiClient } from './useApiClient'

export const useSiteConfig = () => {
  // Cache for config values
  const configCache = useState<Record<string, string>>('siteconfig:cache', () => ({}))
  // Track if we've loaded all configs
  const configsLoaded = useState<boolean>('siteconfig:loaded', () => false)
  const log = useLogger('SiteConfig')

  /**
   * Load all configuration values from the server and populate the cache
   */
  const loadAllConfigs = async () => {
    if (configsLoaded.value) {
      return
    }

    const { apiCall, extractData } = useApiClient()
    const response = await apiCall<Array<{ key: string, value: string }>>('/api/siteconfig')
    const data = extractData(response)

    // Populate cache with all configs (defensive check for array)
    if (Array.isArray(data)) {
      data.forEach((config) => {
        configCache.value[config.key] = config.value
      })
    } else {
      log.warn('Expected array from /api/siteconfig, got:', typeof data)
    }

    configsLoaded.value = true
  }

  /**
   * Get a configuration value by key
   *
   * @param key - The configuration key
   * @param defaultValue - Default value if config not found
   * @returns The configuration value or default
   */
  const getConfig = async (key: string, defaultValue: string = ''): Promise<string> => {
    // Load all configs if not already loaded
    if (!configsLoaded.value) {
      try {
        await loadAllConfigs()
      } catch (error) {
        log.error('Failed to load all configs', error)
        // If loading fails, return default value
        return defaultValue
      }
    }

    // Return from cache if available
    if (configCache.value[key] !== undefined) {
      return configCache.value[key]
    }

    return defaultValue
  }

  /**
   * Get a boolean configuration value by key
   *
   * @param key - The configuration key
   * @param defaultValue - Default value if config not found
   * @returns The configuration value as boolean
   */
  const getConfigBoolean = async (key: string, defaultValue: boolean = false): Promise<boolean> => {
    const value = await getConfig(key, String(defaultValue))
    return value === 'true' || value === '1'
  }

  /**
   * Set a configuration value (requires super-admin)
   *
   * @param key - The configuration key
   * @param value - The configuration value
   * @param description - Optional description
   */
  const setConfig = async (key: string, value: string, description?: string) => {
    try {
      const { apiCall, extractData } = useApiClient()
      const response = await apiCall('/api/super-admin/siteconfig', {
        method: 'POST',
        body: {
          key,
          value,
          description
        }
      })
      const data = extractData(response)

      // Update cache
      configCache.value[key] = value

      return data
    } catch (error) {
      log.error(`Failed to set config for key: ${key}`, error)
      throw error
    }
  }

  /**
   * Get all configuration values (requires super-admin)
   */
  const getAllConfigs = async () => {
    try {
      const { apiCall, extractData } = useApiClient()
      const response = await apiCall<Array<{ key: string, value: string }>>('/api/super-admin/siteconfig')
      const data = extractData(response)
      return data
    } catch (error) {
      log.error('Failed to fetch all configs', error)
      throw error
    }
  }

  /**
   * Clear the configuration cache
   */
  const clearCache = () => {
    configCache.value = {}
    configsLoaded.value = false
  }

  /**
   * Refresh all config values from the server
   */
  const refreshConfig = async (key: string, defaultValue: string = ''): Promise<string> => {
    // Reset loaded flag to force refresh
    configsLoaded.value = false
    await loadAllConfigs()
    return getConfig(key, defaultValue)
  }

  return {
    getConfig,
    getConfigBoolean,
    setConfig,
    getAllConfigs,
    clearCache,
    refreshConfig
  }
}
