/**
 * Settings Page Helpers
 *
 * Shared utilities for settings pages
 */

/**
 * Helper function to convert dot notation to nested object
 * @param {Object} obj - Flat object with dot notation keys
 * @returns {Object} Nested object
 */
export const dotToNested = (obj) => {
  const result = {};

  for (const key in obj) {
    const keys = key.split(".");
    keys.reduce((acc, part, index) => {
      if (index === keys.length - 1) {
        acc[part] = obj[key];
      } else {
        const nextPart = keys[index + 1];
        const nextIsArrayIndex = !isNaN(nextPart);
        if (!acc[part]) {
          acc[part] = nextIsArrayIndex ? [] : {};
        }
      }
      return acc[part];
    }, result);
  }

  return result;
};

/**
 * Helper function to flatten nested object to dot notation
 * Preserves arrays of primitives (strings, numbers, booleans) as arrays
 * Only expands arrays of objects into indexed keys
 * @param {Object} obj - Nested object
 * @param {string} prefix - Key prefix
 * @returns {Object} Flat object with dot notation keys
 */
export const nestedToDot = (obj, prefix = "") => {
  const result = {};

  for (const key in obj) {
    const newKey = prefix ? `${prefix}.${key}` : key;

    if (Array.isArray(obj[key])) {
      // Check if it's an array of primitives (strings, numbers, booleans)
      const isPrimitiveArray = obj[key].every(
        (item) => item === null || typeof item !== "object",
      );

      if (isPrimitiveArray) {
        // Keep primitive arrays as arrays (for MultiSelect, etc.)
        result[newKey] = obj[key];
      } else {
        // Expand arrays of objects into indexed keys (for Repeater, etc.)
        obj[key].forEach((item, index) => {
          if (item !== null && typeof item === "object") {
            Object.assign(result, nestedToDot(item, `${newKey}.${index}`));
          } else {
            result[`${newKey}.${index}`] = item;
          }
        });
      }
    } else if (obj[key] !== null && typeof obj[key] === "object") {
      Object.assign(result, nestedToDot(obj[key], newKey));
    } else {
      result[newKey] = obj[key];
    }
  }

  return result;
};

/**
 * Get API configuration
 * @returns {Object} API config with baseUrl and nonce
 */
export const getApiConfig = () => {
  const { env } = window.arraySubs || {};
  return {
    apiBaseUrl: `${env?.apiBaseUrl || ""}arraysubs/v1`,
    nonce: env?.nonce || "",
  };
};

/**
 * Fetch settings from API
 * @returns {Promise<Object>} Settings data
 */
export const fetchSettings = async () => {
  const { apiBaseUrl, nonce } = getApiConfig();

  const response = await fetch(`${apiBaseUrl}/settings/data`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": nonce,
    },
  });

  if (!response.ok) {
    throw new Error("Failed to load settings");
  }

  const result = await response.json();

  if (result.code !== 200) {
    throw new Error(result.message || "Failed to load settings");
  }

  return result.content.values;
};

/**
 * Save settings to API
 * @param {Object} settings - Settings to save (nested format)
 * @returns {Promise<Object>} Updated settings
 */
export const saveSettings = async (settings) => {
  const { apiBaseUrl, nonce } = getApiConfig();

  const response = await fetch(`${apiBaseUrl}/settings/save`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": nonce,
    },
    body: JSON.stringify({ settings }),
  });

  if (!response.ok) {
    throw new Error("Failed to save settings");
  }

  const result = await response.json();

  if (result.code !== 200) {
    throw new Error(result.message || "Failed to save settings");
  }

  return result.content.values;
};

/**
 * Reset settings to defaults
 * @returns {Promise<Object>} Default settings
 */
export const resetSettings = async () => {
  const { apiBaseUrl, nonce } = getApiConfig();

  const response = await fetch(`${apiBaseUrl}/settings/reset`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": nonce,
    },
  });

  if (!response.ok) {
    throw new Error("Failed to reset settings");
  }

  const result = await response.json();

  if (result.code !== 200) {
    throw new Error(result.message || "Failed to reset settings");
  }

  return result.content.values;
};
