"use strict";

/**
 * Timeout Auto Submit - Scheduled task for automatically submitting workflow instances
 * that have exceeded their step timeout.
 * 
 * Migrated from steedos-platform: creator/packages/steedos-workflow/server/schedule/timeout_auto_submit.coffee
 * 
 * Configuration:
 *   - STEEDOS_CRON_TIMEOUT_AUTO_SUBMIT_INTERVAL: Interval in milliseconds (e.g., 60000 for 1 minute)
 *   - Set via environment variable when STEEDOS_CRON_ENABLED=true
 * 
 * Uses node-schedule for microservice-friendly scheduling instead of setInterval.
 */

const schedule = require('node-schedule');
const UUFlowManager = require('../main/default/manager/uuflow_manager');

const TimeoutAutoSubmit = {};

let _job = null;
let _isProcessing = false;

/**
 * Configure and start the timeout auto-submit scheduled task.
 * @param {Object} options
 * @param {number} options.sendInterval - Interval in milliseconds between checks (default: 60000)
 */
TimeoutAutoSubmit.Configure = function (options = {}) {
    const sendInterval = parseInt(options.sendInterval, 10) || 60000;

    // Stop existing job if any
    if (_job) {
        _job.cancel();
        _job = null;
    }

    console.log(`${new Date().toISOString()} [timeout_auto_submit] Configured with interval: ${sendInterval}ms`);

    // Convert milliseconds interval to a cron-compatible schedule using node-schedule's RecurrenceRule
    const intervalSeconds = Math.max(Math.round(sendInterval / 1000), 1);
    let cronExpression;
    if (intervalSeconds < 60) {
        // Sub-minute: use seconds field
        cronExpression = `*/${intervalSeconds} * * * * *`;
    } else {
        // Minute or longer: use minutes field
        const intervalMinutes = Math.max(Math.round(intervalSeconds / 60), 1);
        cronExpression = `0 */${intervalMinutes} * * * *`;
    }

    _job = schedule.scheduleJob(cronExpression, async function () {
        if (_isProcessing) {
            return;
        }
        _isProcessing = true;
        const startTime = Date.now();
        try {
            await UUFlowManager.timeoutAutoSubmit();
            const duration = Date.now() - startTime;
            if (duration > 5000) {
                console.log(`${new Date().toISOString()} [timeout_auto_submit] Completed in ${duration}ms`);
            }
        } catch (error) {
            const duration = Date.now() - startTime;
            console.error(`${new Date().toISOString()} [timeout_auto_submit] Fatal error after ${duration}ms: ${error.message}`);
            console.error(`${new Date().toISOString()} [timeout_auto_submit] Stack trace:`, error.stack);
        } finally {
            _isProcessing = false;
        }
    });
};

/**
 * Stop the scheduled task.
 */
TimeoutAutoSubmit.Stop = function () {
    if (_job) {
        _job.cancel();
        _job = null;
    }
    _isProcessing = false;
    console.log(`${new Date().toISOString()} [timeout_auto_submit] Stopped`);
};

module.exports = TimeoutAutoSubmit;
