/**
 * Elementor frontend handler for the Countdown widget.
 *
 * Supports:
 *  - Due-date timers   : a fixed UTC target timestamp (computed in PHP).
 *  - Evergreen timers  : a per-visitor duration seeded & persisted in
 *                        localStorage so the deadline survives reloads.
 *
 * On expiry it can keep zeros, swap in a message, hide the timer or redirect.
 * No jQuery dependency inside the tick loop; one interval per instance with
 * editor-safe teardown.
 *
 */

(function ($) {
    'use strict';

    var SECOND = 1000;
    var MINUTE = 60 * SECOND;
    var HOUR = 60 * MINUTE;
    var DAY = 24 * HOUR;

    /**
     * Read & persist the evergreen deadline for a single instance.
     *
     * @param {string} instanceId - Stable per-widget storage key.
     * @param {number} duration   - Countdown length in ms.
     * @returns {number} Absolute deadline timestamp (ms).
     */
    function resolveEvergreenDeadline(instanceId, duration) {
        var key = 'captwiki_cd_' + instanceId;
        var stored = null;

        try {
            stored = window.localStorage.getItem(key);
        } catch (e) {
            stored = null;
        }

        var now = Date.now();
        var deadline = stored ? parseInt(stored, 10) : NaN;

        /* Seed a fresh deadline if missing, invalid, or already long expired. */
        if (isNaN(deadline) || deadline < now - DAY) {
            deadline = now + duration;
            try {
                window.localStorage.setItem(key, String(deadline));
            } catch (e) {
                /* storage blocked — timer still runs for this page view */
            }
        }

        return deadline;
    }

    /**
     * Format a numeric value, optionally zero-padded to two digits.
     *
     * @param {number} value - Non-negative integer.
     * @param {boolean} pad  - Whether to pad to two digits.
     * @returns {string}
     */
    function formatValue(value, pad) {
        if (pad && value < 10) {
            return '0' + value;
        }
        return String(value);
    }

    /**
     * Per-instance handler — called by Elementor for every widget instance.
     *
     * @param {jQuery} $scope - The widget wrapper element.
     */
    var CaptwikiCountdownHandler = function ($scope) {

        var root = $scope[0].querySelector('.captwiki-countdown');
        if (!root) return;

        /* Teardown a previous run (editor re-render safety). */
        if (root._cwkInterval) {
            clearInterval(root._cwkInterval);
            root._cwkInterval = null;
        }

        var type = root.getAttribute('data-type') || 'due_date';
        var pad = root.getAttribute('data-pad') === '1';
        var expireAction = root.getAttribute('data-expire') || 'none';
        var redirect = root.getAttribute('data-redirect') || '';
        var instanceId = root.getAttribute('data-instance') || 'default';

        var timer = root.querySelector('.captwiki-countdown__timer');
        var message = root.querySelector('.captwiki-countdown__message');

        /* Cache each visible unit's digit node. */
        var fields = {};
        root.querySelectorAll('.captwiki-countdown__item').forEach(function (item) {
            var unit = item.getAttribute('data-unit');
            var node = item.querySelector('[data-value]');
            if (unit && node) {
                fields[unit] = node;
            }
        });

        /* Resolve the absolute deadline. */
        var deadline;
        if (type === 'evergreen') {
            var duration = parseInt(root.getAttribute('data-duration'), 10) || 0;
            deadline = resolveEvergreenDeadline(instanceId, duration);
        } else {
            deadline = parseInt(root.getAttribute('data-target'), 10) || 0;
        }

        var expired = false;

        /**
         * Run the expiry behaviour exactly once.
         */
        function handleExpire() {
            if (expired) return;
            expired = true;

            if (expireAction === 'redirect' && redirect) {
                window.location.href = redirect;
                return;
            }

            if (expireAction === 'hide') {
                root.style.display = 'none';
                return;
            }

            if (expireAction === 'message' && message) {
                if (timer) timer.style.display = 'none';
                message.hidden = false;
                root.classList.add('is-expired');
            }
        }

        /**
         * Compute the remaining time and paint the digits.
         */
        function tick() {
            var remaining = deadline - Date.now();

            if (remaining <= 0) {
                remaining = 0;
                paint(0, 0, 0, 0);
                clearInterval(root._cwkInterval);
                root._cwkInterval = null;
                handleExpire();
                return;
            }

            var days = Math.floor(remaining / DAY);
            var hours = Math.floor((remaining % DAY) / HOUR);
            var minutes = Math.floor((remaining % HOUR) / MINUTE);
            var seconds = Math.floor((remaining % MINUTE) / SECOND);

            /* If days are hidden, roll their value into hours. */
            if (!fields.days) {
                hours += days * 24;
            }
            /* If hours are hidden, roll up into minutes, etc. */
            if (!fields.hours) {
                minutes += hours * 60;
            }
            if (!fields.minutes) {
                seconds += minutes * 60;
            }

            paint(days, hours, minutes, seconds);
        }

        /**
         * Write values into the cached digit nodes.
         *
         * @param {number} d Days.
         * @param {number} h Hours.
         * @param {number} m Minutes.
         * @param {number} s Seconds.
         */
        function paint(d, h, m, s) {
            if (fields.days) fields.days.textContent = formatValue(d, pad);
            if (fields.hours) fields.hours.textContent = formatValue(h, pad);
            if (fields.minutes) fields.minutes.textContent = formatValue(m, pad);
            if (fields.seconds) fields.seconds.textContent = formatValue(s, pad);
        }

        /* Already past the deadline on load. */
        if (deadline <= Date.now()) {
            paint(0, 0, 0, 0);
            handleExpire();
            return;
        }

        tick();
        root._cwkInterval = setInterval(tick, SECOND);
    };

    /* ── Register with Elementor frontend ───────────────────── */
    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/captwiki-countdown.default',
            CaptwikiCountdownHandler
        );
    });

})(jQuery);
