import { aggregateEpisodesForSubscriptions } from '../shared/episodes-aggregator.js';
import { getSubscriptions } from '../shared/subscription-store.js';
import { getSettings, subscribeToSettings, SETTINGS_DEFAULTS } from '../shared/settings-store.js';

const AUTO_FETCH_ALARM = 'xyz.autoFetch';
const AUTO_FETCH_PER_PODCAST = 5;
const NEXT_RUN_STORAGE_KEY = 'autoFetchNextAt';
const LAST_RUN_STORAGE_KEY = 'autoFetchLastRunAt';

let currentInterval = SETTINGS_DEFAULTS.autoFetchIntervalMinutes;
let currentSettings = { ...SETTINGS_DEFAULTS };
let isRunning = false;

export function initializeAutoFetch() {
  chrome.alarms.onAlarm.addListener(handleAlarm);

  subscribeToSettings(settings => {
    currentSettings = settings;
    const nextInterval = normalizeInterval(settings.autoFetchIntervalMinutes);
    if (nextInterval !== currentInterval) {
      currentInterval = nextInterval;
      scheduleAutoFetch(currentInterval, { immediate: true });
    }
  });

  getSettings()
    .then(settings => {
      currentSettings = settings;
      currentInterval = normalizeInterval(settings.autoFetchIntervalMinutes);
      scheduleAutoFetch(currentInterval, { immediate: true });
    })
    .catch(error => {
      console.warn('[核桃FM] Failed to load settings for auto fetch:', error);
      currentInterval = normalizeInterval(SETTINGS_DEFAULTS.autoFetchIntervalMinutes);
      scheduleAutoFetch(currentInterval, { immediate: false });
    });

  // 订阅变更由前端处理，auto-fetch 只负责定时更新
}

function handleAlarm(alarm) {
  if (!alarm || alarm.name !== AUTO_FETCH_ALARM) {
    return;
  }
  triggerAutoFetch({ reason: 'scheduled' });
}

async function scheduleAutoFetch(intervalMinutes, { immediate = false } = {}) {
  try {
    await chrome.alarms.clear(AUTO_FETCH_ALARM);
  } catch (error) {
    console.warn('[核桃FM] Failed to clear auto fetch alarm:', error);
  }

  if (!intervalMinutes || intervalMinutes <= 0) {
    persistNextRunTime(null);
    return;
  }

  const delay = Math.max(1, intervalMinutes);
  try {
    await chrome.alarms.create(AUTO_FETCH_ALARM, {
      periodInMinutes: intervalMinutes,
      delayInMinutes: delay,
    });
    updatePersistedNextRun();
  } catch (error) {
    console.error('[核桃FM] Failed to schedule auto fetch alarm:', error);
  }

  if (immediate) {
    // 轻量延迟，避免在安装阶段与其他初始化竞争。
    setTimeout(() => {
      triggerAutoFetch({ reason: 'initial' });
    }, 1000);
  }
}

function triggerAutoFetch({ reason = 'manual', force = true } = {}) {
  if (isRunning) {
    console.log('[核桃FM] Auto fetch already running, skip trigger:', reason);
    return;
  }
  isRunning = true;
  runAutoFetch({ force })
    .catch(error => {
      console.error('[核桃FM] Auto fetch failed:', error);
    })
    .finally(() => {
      isRunning = false;
      persistLastRunTime(Date.now());
      updatePersistedNextRun();
    });
}

async function runAutoFetch({ force = false } = {}) {
  const subscriptions = await getSubscriptions().catch(error => {
    console.error('[核桃FM] Unable to load subscriptions for auto fetch:', error);
    return [];
  });

  if (!Array.isArray(subscriptions) || subscriptions.length === 0) {
    return;
  }

  const maxItems = clampEpisodeLimit(currentSettings?.episodeCacheLimit);

  await aggregateEpisodesForSubscriptions(subscriptions, {
    concurrency: 1,
    limitPerPodcast: AUTO_FETCH_PER_PODCAST,
    maxItems,
    force,
    deferStore: true,
  });
}

function updatePersistedNextRun() {
  if (typeof chrome === 'undefined' || !chrome?.alarms?.get) {
    return;
  }
  chrome.alarms.get(AUTO_FETCH_ALARM, alarm => {
    const nextTime = alarm?.scheduledTime ?? null;
    persistNextRunTime(nextTime);
  });
}

function persistNextRunTime(timestamp) {
  try {
    chrome.storage.local.set({ [NEXT_RUN_STORAGE_KEY]: timestamp ?? null }).catch?.(() => {});
  } catch (error) {
    // chrome.storage.local.set 返回 Promise，可静默异常
  }
}

function persistLastRunTime(timestamp) {
  try {
    chrome.storage.local.set({ [LAST_RUN_STORAGE_KEY]: timestamp ?? null }).catch?.(() => {});
  } catch (error) {
    // ignore
  }
}

function normalizeInterval(value) {
  const num = Number(value);
  if (!Number.isFinite(num) || num <= 0) {
    return 0;
  }
  return Math.min(24 * 60, Math.max(1, Math.round(num)));
}

function clampEpisodeLimit(limit) {
  const num = Number(limit);
  if (!Number.isFinite(num) || num <= 0) {
    return SETTINGS_DEFAULTS.episodeCacheLimit;
  }
  const rounded = Math.round(num);
  return Math.max(50, Math.min(rounded, 5000));
}
