'use strict';

const logger = require('../utils/logger');
const { getJson, postJson } = require('./syncClient');
const { executeCommand } = require('./commandExecutor');

async function pollOnce(config, deps = {}) {
  const limit = Math.min(Math.max(Number(config.commandPollLimit || 20), 1), 50);
  const response = await getJson(config, `/api/agent/commands?limit=${limit}`);
  const commands = response.commands || [];
  for (const command of commands) {
    try {
      await postJson(config, `/api/control-center/agent/commands/${encodeURIComponent(command.command_id)}/processing`, {
        command_id: command.command_id,
        idempotency_key: command.idempotency_key,
      }).catch((err) => {
        if (err.status !== 409) throw err;
      });
      const result = await executeCommand(command, config, deps);
      await postJson(config, `/api/control-center/agent/commands/${encodeURIComponent(command.command_id)}/applied`, {
        command_id: command.command_id,
        idempotency_key: command.idempotency_key,
        result,
      });
    } catch (err) {
      logger.warn({ event: 'agent_command_poll_execute_failed', command_id: command.command_id, command_type: command.command_type, error: err.message });
      await postJson(config, `/api/control-center/agent/commands/${encodeURIComponent(command.command_id)}/failed`, {
        command_id: command.command_id,
        idempotency_key: command.idempotency_key,
        error: err.message,
        code: String(err.code || 'command_error'),
        outcome: err.outcome || null,
      }).catch((reportErr) => {
        logger.warn({ event: 'agent_command_poll_report_failed', command_id: command.command_id, error: reportErr.message });
      });
    }
  }
  return { ok: true, commands: commands.length };
}

function startCommandPoller(config, deps = {}) {
  async function tick() {
    try {
      await pollOnce(config, deps);
    } catch (err) {
      logger.warn({ event: 'agent_command_poll_failed', error: err.message });
    }
  }
  tick();
  const timer = setInterval(tick, Math.max(5, config.commandPollIntervalSeconds || 15) * 1000);
  timer.unref?.();
  return timer;
}

module.exports = { startCommandPoller, pollOnce };
