/**
 * Configuration Utilities
 * Handles app configuration, localStorage persistence, and theme management
 * 
 * Configuration priority:
 * 1. localStorage (user's browser settings)
 * 2. Server config (from .env file)
 * 3. Default values
 */

export const DEFAULT_CONFIG = {
  callsign: 'N0CALL',
  headerSize: 1.0, // Float multiplies base px size (0.1 to 2.0)
  locator: '',
  location: { lat: 40.0150, lon: -105.2705 }, // Boulder, CO (default)
  defaultDX: { lat: 35.6762, lon: 139.6503 }, // Tokyo
  units: 'imperial', // 'imperial' or 'metric'
  theme: 'dark', // 'dark', 'light', 'legacy', or 'retro'
  layout: 'modern', // 'modern' or 'classic'
  timezone: '', // IANA timezone (e.g. 'America/Regina') — empty = browser default
  use12Hour: true,
  showSatellites: true,
  showPota: true,
  showDxPaths: true,
  refreshIntervals: {
    spaceWeather: 300000,   // 5 minutes
    bandConditions: 300000, // 5 minutes
    pota: 120000,           // 2 minutes (was 1 min)
    dxCluster: 30000,       // 30 seconds (was 5 sec)
    terminator: 60000       // 1 minute
  }
};

// Cache for server config
let serverConfig = null;

/**
 * Fetch configuration from server (.env file)
 * This is called once on app startup
 */
export const fetchServerConfig = async () => {
  try {
    const response = await fetch('/api/config');
    if (response.ok) {
      serverConfig = await response.json();
      // Only log if server has real config (not defaults)
      if (serverConfig.callsign && serverConfig.callsign !== 'N0CALL') {
        console.log('[Config] Server config:', serverConfig.callsign, '@', serverConfig.locator);
      }
      return serverConfig;
    }
  } catch (e) {
    console.warn('[Config] Could not fetch server config');
  }
  return null;
};

/**
 * Load config - localStorage is the primary source of truth
 * Server config only provides defaults for first-time users
 */
export const loadConfig = () => {
  // Start with defaults
  let config = { ...DEFAULT_CONFIG };
  
  // Try to load from localStorage FIRST (user's saved settings)
  let localConfig = null;
  try {
    const saved = localStorage.getItem('openhamclock_config');
    if (saved) {
      localConfig = JSON.parse(saved);
      console.log('[Config] Loaded from localStorage:', localConfig.callsign);
    }
  } catch (e) {
    console.error('Error loading config from localStorage:', e);
  }
  
  // If user has localStorage config, use it (this is the priority)
  if (localConfig) {
    config = {
      ...config,
      ...localConfig,
      // Ensure nested objects are properly merged
      location: localConfig.location || config.location,
      defaultDX: localConfig.defaultDX || config.defaultDX,
      refreshIntervals: { ...config.refreshIntervals, ...localConfig.refreshIntervals }
    };
  } 
  // Only use server config if NO localStorage exists (first-time user)
  else if (serverConfig) {
    // Server config provides initial defaults for new users
    // But only if they have real values (not N0CALL)
    config = {
      ...config,
      callsign: (serverConfig.callsign && serverConfig.callsign !== 'N0CALL') 
        ? serverConfig.callsign : config.callsign,
      locator: serverConfig.locator || config.locator,
      location: {
        lat: serverConfig.latitude || config.location.lat,
        lon: serverConfig.longitude || config.location.lon
      },
      defaultDX: {
        lat: serverConfig.dxLatitude || config.defaultDX.lat,
        lon: serverConfig.dxLongitude || config.defaultDX.lon
      },
      units: serverConfig.units || config.units,
      theme: serverConfig.theme || config.theme,
      layout: serverConfig.layout || config.layout,
      timezone: serverConfig.timezone || config.timezone,
      use12Hour: serverConfig.timeFormat === '12',
      showSatellites: serverConfig.showSatellites ?? config.showSatellites,
      showPota: serverConfig.showPota ?? config.showPota,
      showDxPaths: serverConfig.showDxPaths ?? config.showDxPaths
    };
  }
  
  // Mark if config needs setup (no callsign set anywhere)
  config.configIncomplete = (config.callsign === 'N0CALL' || !config.locator);
  
  // Always inject version from server (not a user preference — server is source of truth)
  if (serverConfig?.version) {
    config.version = serverConfig.version;
  }
  
  return config;
};

/**
 * Save config to localStorage
 */
export const saveConfig = (config) => {
  try {
    localStorage.setItem('openhamclock_config', JSON.stringify(config));
    console.log('[Config] Saved to localStorage');
  } catch (e) {
    console.error('[Config] Error saving to localStorage:', e);
  }
};

/**
 * Check if configuration is incomplete (show setup wizard)
 */
export const isConfigIncomplete = () => {
  const config = loadConfig();
  return config.callsign === 'N0CALL' || !config.locator;
};

/**
 * Apply theme to document
 */
export const applyTheme = (theme) => {
  document.documentElement.setAttribute('data-theme', theme);
};

/**
 * Map Tile Providers
 */
export const MAP_STYLES = {
  dark: {
    name: 'Dark',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  satellite: {
    name: 'Satellite',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  terrain: {
    name: 'Terrain',
    url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
    attribution: '&copy; <a href="https://opentopomap.org">OpenTopoMap</a>'
  },
  streets: {
    name: 'Streets',
    url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
  },
  topo: {
    name: 'Topo',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  watercolor: {
    name: 'Ocean',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  hybrid: {
    name: 'Hybrid',
    url: 'https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}',
    attribution: '&copy; Google'
  },
  gray: {
    name: 'Gray',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  political: {
    name: 'Political',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri'
  },
  natgeo: {
    name: 'Nat Geo',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri, National Geographic'
  },
  countries: {
    name: 'Countries',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; Esri, Natural Earth',
    countriesOverlay: true
  }
};

export default {
  DEFAULT_CONFIG,
  fetchServerConfig,
  loadConfig,
  saveConfig,
  isConfigIncomplete,
  applyTheme,
  MAP_STYLES
};
