// ========== THEME CONTROLLER ==========
// User-created themes are stored server-side as individual JSON files.
// localStorage caches them for instant load; server is source of truth.
(function () {
  var THEME_KEY = 'theme';
  var USER_THEMES_KEY = 'user-themes';
  var LEGACY_CUSTOM_KEY = 'custom-theme';

  var BUILTIN_THEMES = ['dark', 'light', 'blue', 'black', 'nord', 'dracula', 'solarized-dark', 'solarized-light', 'taxi', 'ocean'];
  var THEMES = BUILTIN_THEMES.slice();

  var THEME_PROPS = [
    'bg', 'fg', 'muted', 'fg-muted', 'card-base', 'card-bg', 'border',
    'hover', 'card-hover', 'base',
    'ok-bg', 'ok-fg', 'bad-bg', 'bad-fg', 'dot-ok', 'dot-bad', 'uptime',
    'success', 'error', 'warning',
    'accent', 'accent-strong'
  ];

  // Base props the user picks in the builder (subset of THEME_PROPS)
  var BASE_PROPS = [
    'bg', 'fg', 'muted', 'card-base', 'card-bg', 'border',
    'ok-bg', 'ok-fg', 'bad-bg', 'bad-fg', 'dot-ok', 'dot-bad', 'uptime',
    'accent', 'accent-strong'
  ];

  // Props that are auto-derived if not explicitly set
  var DERIVED_PROPS = ['fg-muted', 'hover', 'card-hover', 'base', 'success', 'error', 'warning'];

  var THEME_COLORS = {
    dark:             { bg: '#0b0f1a', fg: '#e8ecf5', muted: '#9aa6bf', 'fg-muted': '#6b7a94', 'card-base': '#121826', 'card-bg': '#121826', border: '#263552', hover: '#1a2235', 'card-hover': '#161e2e', base: '#151c2b', 'ok-bg': '#0c2430', 'ok-fg': '#7ef2ff', 'bad-bg': '#2a121a', 'bad-fg': '#ff9aa3', 'dot-ok': '#35d1ff', 'dot-bad': '#ff5f7a', uptime: '#35d1ff', success: '#4caf50', error: '#e74c3c', warning: '#f39c12', accent: '#8FD6FF', 'accent-strong': '#1F7BFF' },
    light:            { bg: '#f6f7fb', fg: '#0f1115', muted: '#5f6b7a', 'fg-muted': '#8993a4', 'card-base': '#ffffff', 'card-bg': '#ffffff', border: '#e2e7ef', hover: '#eef1f6', 'card-hover': '#f5f6fa', base: '#ebeef3', 'ok-bg': '#eafff1', 'ok-fg': '#0a7c3a', 'bad-bg': '#ffefef', 'bad-fg': '#b00020', 'dot-ok': '#0fb15a', 'dot-bad': '#d93b3b', uptime: '#0fb15a', success: '#0a7c3a', error: '#b00020', warning: '#d68a00', accent: '#4a90d9', 'accent-strong': '#2563eb', lightBg: true },
    blue:             { bg: '#1908AC', fg: '#e8f1ff', muted: '#d6e2ff', 'fg-muted': '#9eafdb', 'card-base': '#0d1533', 'card-bg': '#0d1533', border: '#1c2d6a', hover: '#141f4a', 'card-hover': '#111a3e', base: '#0f1840', 'ok-bg': '#162040', 'ok-fg': '#edffff', 'bad-bg': '#0a0e24', 'bad-fg': '#ffb3c0', 'dot-ok': '#c7e5ff', 'dot-bad': '#ffd6dc', uptime: '#7ec8ff', success: '#7ec8ff', error: '#ffb3c0', warning: '#ffd080', accent: '#9cd4ff', 'accent-strong': '#6fb2ff' },
    black:            { bg: '#0e0e0e', fg: '#f5f5f5', muted: '#999999', 'fg-muted': '#666666', 'card-base': '#1a1a1a', 'card-bg': '#1a1a1a', border: '#2e2e2e', hover: '#242424', 'card-hover': '#202020', base: '#161616', 'ok-bg': '#0f2a12', 'ok-fg': '#66ff7a', 'bad-bg': '#2a0f0f', 'bad-fg': '#ff6b6b', 'dot-ok': '#4caf50', 'dot-bad': '#ff4444', uptime: '#e0e0e0', success: '#4caf50', error: '#ff4444', warning: '#ff9800', accent: '#E63946', 'accent-strong': '#C62828' },
    nord:             { bg: '#2e3440', fg: '#eceff4', muted: '#81a1c1', 'fg-muted': '#6882a0', 'card-base': '#3b4252', 'card-bg': '#3b4252', border: '#4c566a', hover: '#434c5e', 'card-hover': '#3f4858', base: '#353c4a', 'ok-bg': '#2d4f3e', 'ok-fg': '#a3be8c', 'bad-bg': '#4a2c2a', 'bad-fg': '#bf616a', 'dot-ok': '#a3be8c', 'dot-bad': '#bf616a', uptime: '#a3be8c', success: '#a3be8c', error: '#bf616a', warning: '#ebcb8b', accent: '#88c0d0', 'accent-strong': '#5e81ac' },
    dracula:          { bg: '#282a36', fg: '#f8f8f2', muted: '#6272a4', 'fg-muted': '#515d85', 'card-base': '#44475a', 'card-bg': '#44475a', border: '#6272a4', hover: '#4e5170', 'card-hover': '#494c63', base: '#363848', 'ok-bg': '#1e3a2e', 'ok-fg': '#50fa7b', 'bad-bg': '#3d1a1a', 'bad-fg': '#ff5555', 'dot-ok': '#50fa7b', 'dot-bad': '#ff5555', uptime: '#50fa7b', success: '#50fa7b', error: '#ff5555', warning: '#f1fa8c', accent: '#bd93f9', 'accent-strong': '#8be9fd' },
    'solarized-dark': { bg: '#002b36', fg: '#839496', muted: '#586e75', 'fg-muted': '#4a5f65', 'card-base': '#073642', 'card-bg': '#073642', border: '#586e75', hover: '#0d4050', 'card-hover': '#0a3a48', base: '#053340', 'ok-bg': '#0d3d2c', 'ok-fg': '#859900', 'bad-bg': '#3d1a1a', 'bad-fg': '#dc322f', 'dot-ok': '#859900', 'dot-bad': '#dc322f', uptime: '#b5bd68', success: '#859900', error: '#dc322f', warning: '#b58900', accent: '#268bd2', 'accent-strong': '#2aa198' },
    'solarized-light':{ bg: '#fdf6e3', fg: '#657b83', muted: '#93a1a1', 'fg-muted': '#adb8b8', 'card-base': '#eee8d5', 'card-bg': '#eee8d5', border: '#93a1a1', hover: '#e6dfcb', 'card-hover': '#eae3cf', base: '#e8e1cd', 'ok-bg': '#e8f5e8', 'ok-fg': '#859900', 'bad-bg': '#fdf2f2', 'bad-fg': '#dc322f', 'dot-ok': '#859900', 'dot-bad': '#dc322f', uptime: '#859900', success: '#859900', error: '#dc322f', warning: '#b58900', accent: '#268bd2', 'accent-strong': '#2aa198', lightBg: true },
    taxi:             { bg: '#f3d321', fg: '#0e0e00', muted: '#4a4a10', 'fg-muted': '#6b6b30', 'card-base': '#ffd700', 'card-bg': '#ffd700', border: '#b8a840', hover: '#ffe84d', 'card-hover': '#ffe033', base: '#f0d000', 'ok-bg': '#d4ffd9', 'ok-fg': '#0f2a0f', 'bad-bg': '#ffd4d4', 'bad-fg': '#2a0f0f', 'dot-ok': '#4caf50', 'dot-bad': '#ff4444', uptime: '#0e0e00', success: '#2e7d32', error: '#c62828', warning: '#e65100', accent: '#7a4a00', 'accent-strong': '#5c3800', lightBg: true },
    ocean:            { bg: '#2060b0', fg: '#faf5eb', muted: '#dcd2c0', 'fg-muted': '#b0a890', 'card-base': '#7a94ed', 'card-bg': '#7a94ed', border: '#deb67a', hover: '#8aa0f0', 'card-hover': '#8298e8', base: '#6888e0', 'ok-bg': '#4f5bb0', 'ok-fg': '#c7d7eb', 'bad-bg': '#f41a3a', 'bad-fg': '#6a1818', 'dot-ok': '#30a050', 'dot-bad': '#d04040', uptime: '#2d32f2', success: '#30a050', error: '#d04040', warning: '#e6a030', accent: '#1860a0', 'accent-strong': '#104080' },
  };

  // ─── Color helpers ───────────────────────────────

  function hexToRgb(hex) {
    if (!hex || typeof hex !== 'string') return { r: 0, g: 0, b: 0 };
    hex = hex.replace('#', '');
    if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
    return {
      r: parseInt(hex.substr(0, 2), 16) || 0,
      g: parseInt(hex.substr(2, 2), 16) || 0,
      b: parseInt(hex.substr(4, 2), 16) || 0
    };
  }

  function rgbToHex(r, g, b) {
    return '#' + [r, g, b].map(function (x) {
      var h = Math.max(0, Math.min(255, Math.round(x))).toString(16);
      return h.length === 1 ? '0' + h : h;
    }).join('');
  }

  function blendColors(hex1, hex2, ratio) {
    var c1 = hexToRgb(hex1);
    var c2 = hexToRgb(hex2);
    return rgbToHex(
      c1.r + (c2.r - c1.r) * ratio,
      c1.g + (c2.g - c1.g) * ratio,
      c1.b + (c2.b - c1.b) * ratio
    );
  }

  function hexLuminance(hex) {
    hex = hex.replace('#', '');
    if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
    var r = parseInt(hex.substr(0, 2), 16) / 255;
    var g = parseInt(hex.substr(2, 2), 16) / 255;
    var b = parseInt(hex.substr(4, 2), 16) / 255;
    r = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4);
    g = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4);
    b = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4);
    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  }

  // ─── Auto-derive extended colors from base palette ───────────

  function deriveExtendedColors(colors) {
    var bg = colors.bg || '#0b0f1a';
    var fg = colors.fg || '#e8ecf5';
    var muted = colors.muted || '#9aa6bf';
    var cardBase = colors['card-base'] || colors.bg || '#121826';
    var dotOk = colors['dot-ok'] || '#4caf50';
    var dotBad = colors['dot-bad'] || '#e74c3c';
    var isLight = colors.lightBg || (bg && hexLuminance(bg) > 0.4);

    var derived = {};

    // hover: subtle shift of card-base toward fg (dark) or toward bg (light)
    derived.hover = isLight
      ? blendColors(cardBase, bg, 0.35)
      : blendColors(cardBase, fg, 0.08);

    // card-hover: midpoint between card-base and hover
    derived['card-hover'] = blendColors(cardBase, derived.hover, 0.5);

    // base: subdued background between bg and card-base
    derived.base = blendColors(bg, cardBase, 0.6);

    // fg-muted: dimmer than muted, blend toward bg
    derived['fg-muted'] = blendColors(muted, bg, 0.35);

    // success: reuse dot-ok (the green of this theme)
    derived.success = dotOk;

    // error: reuse dot-bad (the red of this theme)
    derived.error = dotBad;

    // warning: warm amber, adjusted for contrast
    derived.warning = isLight ? '#d68a00' : '#f39c12';

    return derived;
  }

  // ─── Generate body background CSS for user themes ───────────

  function generateBodyBackgroundCSS(slug, colors) {
    var isLight = colors.lightBg || (colors.bg && hexLuminance(colors.bg) > 0.4);
    var accent = colors.accent || colors['accent-strong'] || '#888888';
    var accentRgb = hexToRgb(accent);

    if (isLight) {
      return ':root.' + slug + ' body {\n' +
        '  background:\n' +
        '    radial-gradient(1200px 800px at 10% -10%, rgba(' + accentRgb.r + ',' + accentRgb.g + ',' + accentRgb.b + ', .08), transparent 60%),\n' +
        '    radial-gradient(1000px 700px at 110% 10%, rgba(' + accentRgb.r + ',' + accentRgb.g + ',' + accentRgb.b + ', .05), transparent 55%),\n' +
        '    var(--bg);\n' +
        '}\n';
    } else {
      return ':root.' + slug + ' body {\n' +
        '  background:\n' +
        '    radial-gradient(1200px 900px at 8% -12%, rgba(' + accentRgb.r + ',' + accentRgb.g + ',' + accentRgb.b + ', .10), transparent 60%),\n' +
        '    radial-gradient(1000px 700px at 110% -10%, rgba(' + accentRgb.r + ',' + accentRgb.g + ',' + accentRgb.b + ', .07), transparent 55%),\n' +
        '    var(--bg);\n' +
        '}\n';
    }
  }

  // ─── Generate button hover CSS for user themes ───────────

  function generateButtonHoverCSS(slug, colors) {
    var isLight = colors.lightBg || (colors.bg && hexLuminance(colors.bg) > 0.4);

    if (isLight) {
      return ':root.' + slug + ' button:hover {\n' +
        '  background: color-mix(in srgb, var(--accent-strong) 12%, white 88%);\n' +
        '  border-color: rgba(0, 0, 0, .15);\n' +
        '  box-shadow: 0 1px 6px rgba(0, 0, 0, .08), inset 0 1px 0 rgba(255, 255, 255, .8);\n' +
        '}\n';
    } else {
      return ':root.' + slug + ' button:hover {\n' +
        '  background: color-mix(in srgb, var(--accent) 18%, transparent);\n' +
        '  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));\n' +
        '}\n';
    }
  }

  // ─── Core theme functions ───────────────────────────────

  function getSystemTheme() {
    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  }

  function clearCustomProperties() {
    THEME_PROPS.forEach(function (prop) {
      document.documentElement.style.removeProperty('--' + prop);
    });
  }

  function slugify(name, currentSlug) {
    var slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
    if (!slug) slug = 'custom';
    if (BUILTIN_THEMES.indexOf(slug) !== -1) slug = slug + '-custom';
    var cached = safeGetJSON(USER_THEMES_KEY, {});
    var base = slug;
    var counter = 2;
    while (cached[slug] && slug !== currentSlug) {
      slug = base + '-' + counter++;
    }
    return slug;
  }

  // Inject user themes from a themes object into DOM + runtime
  function injectUserThemeStyles(themesData) {
    var existing = document.getElementById('user-theme-styles');
    if (existing) existing.remove();

    THEMES.length = BUILTIN_THEMES.length;
    Object.keys(THEME_COLORS).forEach(function (k) {
      if (BUILTIN_THEMES.indexOf(k) === -1) delete THEME_COLORS[k];
    });

    // Use provided data, or fall back to localStorage cache
    var userThemes = themesData || safeGetJSON(USER_THEMES_KEY, {});
    var slugs = Object.keys(userThemes);

    // Filter out any user themes that collide with built-in slugs
    slugs = slugs.filter(function (s) { return BUILTIN_THEMES.indexOf(s) === -1; });

    if (!slugs.length) return;

    var css = '';
    slugs.forEach(function (slug) {
      var theme = userThemes[slug];
      if (THEMES.indexOf(slug) === -1) THEMES.push(slug);

      // Build color map from saved data
      var colorMap = {};
      THEME_PROPS.forEach(function (p) { if (theme[p]) colorMap[p] = theme[p]; });
      colorMap['card-bg'] = theme['card-base'] || theme.bg;
      if (theme.lightBg) colorMap.lightBg = true;

      // Auto-derive any missing extended colors
      var derived = deriveExtendedColors(colorMap);
      DERIVED_PROPS.forEach(function (p) {
        if (!colorMap[p] && derived[p]) colorMap[p] = derived[p];
      });

      THEME_COLORS[slug] = colorMap;

      // Emit main variable block
      css += ':root.' + slug + ' {\n';
      THEME_PROPS.forEach(function (p) {
        if (colorMap[p]) css += '  --' + p + ': ' + colorMap[p] + ';\n';
      });
      css += '}\n';

      // Emit body background gradient
      css += generateBodyBackgroundCSS(slug, colorMap);

      // Emit button hover override
      css += generateButtonHoverCSS(slug, colorMap);
    });

    var style = document.createElement('style');
    style.id = 'user-theme-styles';
    style.textContent = css;
    document.head.appendChild(style);
  }

  // Fetch themes from server, update cache, re-inject if changed
  function syncThemesFromServer() {
    secureFetch('/api/v1/themes').then(function (r) { return r.json(); }).then(function (data) {
      if (!data.success || !data.themes) return;
      var serverThemes = data.themes;
      var cached = safeGetJSON(USER_THEMES_KEY, {});
      // Only update if different
      if (JSON.stringify(serverThemes) !== JSON.stringify(cached)) {
        safeSet(USER_THEMES_KEY, JSON.stringify(serverThemes));
        injectUserThemeStyles(serverThemes);
        // Re-apply current theme in case it was just synced
        var current = safeGet(THEME_KEY);
        if (current && THEMES.indexOf(current) !== -1) {
          applyTheme(current);
        }
      }
    }).catch(function () {});
  }

  // Migrate legacy custom-theme to server
  function migrateLegacyCustomTheme() {
    var legacy = safeGetJSON(LEGACY_CUSTOM_KEY);
    if (!legacy) return;

    var name = legacy.name || 'Custom';
    var slug = slugify(name);

    var themeData = { name: name };
    THEME_PROPS.forEach(function (p) {
      if (legacy[p]) themeData[p] = legacy[p];
    });

    // Save to localStorage cache immediately
    var cached = safeGetJSON(USER_THEMES_KEY, {});
    cached[slug] = themeData;
    safeSet(USER_THEMES_KEY, JSON.stringify(cached));

    // Update active theme reference
    if (safeGet(THEME_KEY) === 'custom') {
      safeSet(THEME_KEY, slug);
    }

    safeRemove(LEGACY_CUSTOM_KEY);

    // Also push to server
    var colors = {};
    THEME_PROPS.forEach(function (p) { if (themeData[p]) colors[p] = themeData[p]; });
    fetch('/api/v1/themes/' + slug, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: name, colors: colors })
    }).catch(function () {});
  }

  function applyTheme(mode) {
    document.documentElement.classList.add('theme-transitioning');

    THEMES.forEach(function (t) {
      if (t !== 'dark') document.documentElement.classList.remove(t);
    });

    clearCustomProperties();

    if (mode !== 'dark') {
      document.documentElement.classList.add(mode);
    }

    safeSet(THEME_KEY, mode);

    var colors = THEME_COLORS[mode];
    var meta = document.querySelector('meta[name="theme-color"]');
    if (meta && colors) meta.setAttribute('content', colors.bg);

    // Toggle light-bg class: explicit flag first, then auto-detect from luminance
    var isLight = colors && colors.lightBg;
    if (!isLight && colors && colors.bg) isLight = hexLuminance(colors.bg) > 0.4;
    if (isLight) {
      document.documentElement.classList.add('light-bg');
    } else {
      document.documentElement.classList.remove('light-bg');
    }

    setTimeout(function () {
      document.documentElement.classList.remove('theme-transitioning');
    }, 300);
  }

  // --- Initialization ---
  migrateLegacyCustomTheme();
  // Instant load from cache
  injectUserThemeStyles();

  var savedTheme = safeGet(THEME_KEY);
  if (savedTheme === 'red') { savedTheme = 'black'; safeSet(THEME_KEY, 'black'); }
  if (savedTheme && savedTheme !== 'dark' && THEMES.indexOf(savedTheme) === -1) {
    savedTheme = null;
  }
  applyTheme(savedTheme || getSystemTheme());

  // Sync from server in background (updates cache if server has newer data)
  syncThemesFromServer();

  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function (e) {
    if (!safeGet(THEME_KEY)) {
      applyTheme(e.matches ? 'dark' : 'light');
    }
  });

  // Expose API
  window.THEMES = THEMES;
  window.BUILTIN_THEMES = BUILTIN_THEMES;
  window.THEME_COLORS = THEME_COLORS;
  window.THEME_PROPS = THEME_PROPS;
  window.BASE_PROPS = BASE_PROPS;
  window.DERIVED_PROPS = DERIVED_PROPS;
  window.USER_THEMES_KEY = USER_THEMES_KEY;
  window.applyTheme = applyTheme;
  window.clearCustomProperties = clearCustomProperties;
  window.injectUserThemeStyles = injectUserThemeStyles;
  window.syncThemesFromServer = syncThemesFromServer;
  window.slugifyThemeName = slugify;
  window.getActiveTheme = function () { return safeGet(THEME_KEY) || getSystemTheme(); };
  window.deriveExtendedColors = deriveExtendedColors;
  window.hexToRgb = hexToRgb;
  window.rgbToHex = rgbToHex;
  window.blendColors = blendColors;
})();
