const SETTINGS_STORAGE_KEY = 'xyzSettings';

const SETTINGS_DEFAULTS = {
  autoFetchIntervalMinutes: 120,
  podcastCacheLimit: 200,
  episodeCacheLimit: 600,
  autoClearCacheThresholdMb: 256,
  showCacheCounts: false,
  enablePlayerDebugLogs: false,
  playerDebugLogLimit: 200,
};

let cachedSettings = { ...SETTINGS_DEFAULTS };
let isLoaded = false;

/**
 * 读取设置，返回带默认值的对象。
 */
export async function getSettings() {
  if (!isLoaded) {
    await loadSettingsFromStorage();
  }
  return { ...cachedSettings };
}

/**
 * 使用部分字段更新设置并返回最新结果。
 */
export async function updateSettings(patch = {}) {
  const next = normalizeSettings({ ...cachedSettings, ...patch });
  cachedSettings = next;
  await chrome.storage.sync.set({ [SETTINGS_STORAGE_KEY]: next });
  return { ...cachedSettings };
}

/**
 * 覆盖写入设置。
 */
export async function setSettings(settings) {
  const next = normalizeSettings(settings);
  cachedSettings = next;
  await chrome.storage.sync.set({ [SETTINGS_STORAGE_KEY]: next });
  return { ...cachedSettings };
}

/**
 * 订阅设置变更，返回移除监听的函数。
 */
export function subscribeToSettings(callback) {
  if (typeof callback !== 'function') {
    return () => {};
  }
  const listener = (changes, areaName) => {
    if (areaName !== 'sync' || !changes[SETTINGS_STORAGE_KEY]) {
      return;
    }
    const { newValue } = changes[SETTINGS_STORAGE_KEY];
    const normalized = normalizeSettings(newValue);
    cachedSettings = normalized;
    callback({ ...cachedSettings });
  };
  chrome.storage.onChanged.addListener(listener);
  if (isLoaded) {
    // 立即推送一次当前配置，保持行为一致。
    callback({ ...cachedSettings });
  } else {
    loadSettingsFromStorage().then(() => callback({ ...cachedSettings })).catch(() => {});
  }
  return () => {
    chrome.storage.onChanged.removeListener(listener);
  };
}

/**
 * 返回带默认值、已规范化的设置对象。
 */
export function normalizeSettings(input) {
  const base = typeof input === 'object' && input ? { ...input } : {};
  const normalized = {
    autoFetchIntervalMinutes: clampNumber(base.autoFetchIntervalMinutes, SETTINGS_DEFAULTS.autoFetchIntervalMinutes, {
      min: 60,
      max: 24 * 60,
    }),
    podcastCacheLimit: clampNumber(base.podcastCacheLimit, SETTINGS_DEFAULTS.podcastCacheLimit, { min: 50, max: 2000 }),
    episodeCacheLimit: clampNumber(base.episodeCacheLimit, SETTINGS_DEFAULTS.episodeCacheLimit, { min: 100, max: 5000 }),
    autoClearCacheThresholdMb: clampNumber(
      base.autoClearCacheThresholdMb,
      SETTINGS_DEFAULTS.autoClearCacheThresholdMb,
      { min: 0, max: 2048 }
    ),
    showCacheCounts: Boolean(base.showCacheCounts),
    enablePlayerDebugLogs: Boolean(base.enablePlayerDebugLogs),
    playerDebugLogLimit: clampNumber(base.playerDebugLogLimit, SETTINGS_DEFAULTS.playerDebugLogLimit, { min: 200, max: 5000 }),
  };
  return normalized;
}

export { SETTINGS_DEFAULTS };

async function loadSettingsFromStorage() {
  try {
    const stored = await chrome.storage.sync.get({ [SETTINGS_STORAGE_KEY]: SETTINGS_DEFAULTS });
    const existing = stored?.[SETTINGS_STORAGE_KEY];
    cachedSettings = normalizeSettings(existing);
  } catch (error) {
    console.warn('[核桃FM] Failed to load settings from storage:', error);
    cachedSettings = { ...SETTINGS_DEFAULTS };
  } finally {
    isLoaded = true;
  }
  return cachedSettings;
}

function clampNumber(value, fallback, { min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY } = {}) {
  const num = Number(value);
  if (!Number.isFinite(num)) {
    return fallback;
  }
  if (num < min) {
    return min;
  }
  if (num > max) {
    return max;
  }
  return Math.round(num);
}
