export function startScheduleReminderWorker({
  scheduleService,
  sendWechatTextToUser,
  logger = console,
  intervalMs = Number(process.env.H5_REMINDER_SCAN_INTERVAL_MS ?? 30_000),
  maxAttempts = Number(process.env.H5_REMINDER_MAX_ATTEMPTS ?? 5),
  runOnStart = true,
} = {}) {
  if (!scheduleService || typeof sendWechatTextToUser !== 'function') {
    return { stop() {} };
  }

  let stopped = false;
  let running = false;

  const runOnce = async () => {
    if (running || stopped) return;
    running = true;
    try {
      const due = await scheduleService.listDueDigestSubscriptions({ limit: 50 });
      for (const candidate of due) {
        const subscription = await scheduleService.lockDigestSubscription(candidate.id);
        if (!subscription) continue;
        try {
          const text = await scheduleService.buildTodoDigestText({
            userId: subscription.userId,
            timezone: subscription.timezone,
          });
          await scheduleService.createUserNotification?.({
            userId: subscription.userId,
            channel: 'web',
            notificationType: 'todo_digest',
            title: '今日待办摘要',
            body: text,
            data: {
              subscriptionId: subscription.id,
              timezone: subscription.timezone,
            },
          });
          await sendWechatTextToUser(subscription.userId, text);
          await scheduleService.logDelivery({
            subscriptionId: subscription.id,
            userId: subscription.userId,
            channel: subscription.channel,
            status: 'success',
          });
          await scheduleService.markDigestSent(subscription);
        } catch (err) {
          logger.warn?.('Schedule digest delivery failed:', err);
          await scheduleService.logDelivery({
            subscriptionId: subscription.id,
            userId: subscription.userId,
            channel: subscription.channel,
            status: 'failed',
            errorMessage: err instanceof Error ? err.message : String(err),
          }).catch(() => {});
          await scheduleService.markDigestFailed(subscription, err, { maxAttempts });
        }
      }
      const dueBalance = await scheduleService.listDueBalanceAlerts({ limit: 50 });
      for (const candidate of dueBalance) {
        const subscription = await scheduleService.lockBalanceAlert(candidate.id);
        if (!subscription) continue;
        try {
          const user = await scheduleService.getUserWalletSnapshot?.(subscription.userId);
          const balanceCents = Number(user?.balanceCents ?? user?.balance_cents ?? 0);
          if (balanceCents > subscription.thresholdCents) {
            await scheduleService.markBalanceAlertSent({
              ...subscription,
              lastNotifiedBalanceCents: balanceCents,
            });
            continue;
          }
          const yuan = (subscription.thresholdCents / 100).toFixed(2);
          const text = `余额不足提醒\n\n你的账户余额已低于 ${yuan} 元，请及时充值。`;
          await scheduleService.createUserNotification?.({
            userId: subscription.userId,
            channel: 'web',
            notificationType: 'balance_low',
            title: '余额不足提醒',
            body: text,
            data: {
              thresholdCents: subscription.thresholdCents,
              balanceCents,
            },
          });
          await sendWechatTextToUser(subscription.userId, text);
          await scheduleService.logDelivery({
            subscriptionId: subscription.id,
            userId: subscription.userId,
            channel: subscription.channel,
            status: 'success',
          });
          await scheduleService.markBalanceAlertSent({
            ...subscription,
            lastNotifiedBalanceCents: balanceCents,
          });
        } catch (err) {
          logger.warn?.('Balance alert delivery failed:', err);
          await scheduleService.logDelivery({
            subscriptionId: subscription.id,
            userId: subscription.userId,
            channel: subscription.channel,
            status: 'failed',
            errorMessage: err instanceof Error ? err.message : String(err),
          }).catch(() => {});
          await scheduleService.markBalanceAlertFailed(subscription, err, { maxAttempts });
        }
      }
    } catch (err) {
      logger.warn?.('Schedule reminder worker failed:', err);
    } finally {
      running = false;
    }
  };

  const timer = setInterval(runOnce, Math.max(1000, Number(intervalMs) || 30_000));
  timer.unref?.();
  if (runOnStart) void runOnce();

  return {
    runOnce,
    stop() {
      stopped = true;
      clearInterval(timer);
    },
  };
}
