<?php
/**
 * Global Pulse data helper.
 *
 * Module-local service for the Global Pulse module.
 * Kept with the same public function/class names for backward compatibility
 * while moving ownership out of the central includes/ kernel.
 *
 * @package Noesia_Smart_Waiter
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

if ( ! function_exists( 'noesia_swa_global_pulse_get_planet_days' ) ) {
    /**
     * Return a curated list of widely recognized global observances.
     *
     * @param int|null $year Calendar year.
     * @return array<int, array<string, mixed>>
     */
    function noesia_swa_global_pulse_get_planet_days( $year = null ) {
        $year = $year ? absint( $year ) : (int) gmdate( 'Y' );

        $items = array(
            array(
                'kind'  => 'fixed',
                'date'  => '01-01',
                'title' => __( 'Global Family Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Widely shared as a worldwide day of peace and togetherness.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '02-09',
                'title' => __( 'World Pizza Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Popular worldwide food celebration.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '02-14',
                'title' => __( 'Valentine\'s Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Globally observed celebration of love and affection.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '03-08',
                'title' => __( 'International Women\'s Day', 'noesia-smart-waiter' ),
                'note'  => __( 'International observance recognized across many countries.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '03-20',
                'title' => __( 'International Day of Happiness', 'noesia-smart-waiter' ),
                'note'  => __( 'A positive global awareness day.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '03-21',
                'title' => __( 'World Poetry Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Celebrates language, creativity and culture.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '04-07',
                'title' => __( 'World Health Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Global health awareness observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '04-22',
                'title' => __( 'Earth Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Worldwide environmental awareness day.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '05-15',
                'title' => __( 'International Day of Families', 'noesia-smart-waiter' ),
                'note'  => __( 'Recognized internationally as a family-focused observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '06-05',
                'title' => __( 'World Environment Day', 'noesia-smart-waiter' ),
                'note'  => __( 'One of the best-known global environment campaigns.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '06-21',
                'title' => __( 'International Day of Yoga', 'noesia-smart-waiter' ),
                'note'  => __( 'International wellness and mindfulness observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '07-07',
                'title' => __( 'World Chocolate Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Popular international food celebration.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '07-30',
                'title' => __( 'International Day of Friendship', 'noesia-smart-waiter' ),
                'note'  => __( 'A worldwide social observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'     => 'dynamic',
                'pattern'  => 'first friday of august',
                'title'    => __( 'International Beer Day', 'noesia-smart-waiter' ),
                'note'     => __( 'Moves each year: first Friday of August.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '09-21',
                'title' => __( 'International Day of Peace', 'noesia-smart-waiter' ),
                'note'  => __( 'A widely known global peace observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '09-27',
                'title' => __( 'World Tourism Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Important for travel, hospitality and destination awareness.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '10-01',
                'title' => __( 'International Coffee Day', 'noesia-smart-waiter' ),
                'note'  => __( 'A strong match for cafés, bars and hospitality venues.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '10-04',
                'title' => __( 'World Animal Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Widely recognized international awareness day.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '10-16',
                'title' => __( 'World Food Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Major worldwide food and agriculture observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '11-13',
                'title' => __( 'World Kindness Day', 'noesia-smart-waiter' ),
                'note'  => __( 'A simple, positive worldwide observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '11-21',
                'title' => __( 'World Hello Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Global communication and goodwill observance.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '12-05',
                'title' => __( 'International Volunteer Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Recognized across many countries and organizations.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '12-25',
                'title' => __( 'Christmas Day', 'noesia-smart-waiter' ),
                'note'  => __( 'Widely observed internationally.', 'noesia-smart-waiter' ),
            ),
            array(
                'kind'  => 'fixed',
                'date'  => '12-31',
                'title' => __( 'New Year\'s Eve', 'noesia-smart-waiter' ),
                'note'  => __( 'Global year-end celebration.', 'noesia-smart-waiter' ),
            ),
        );

        $rows = array();

        foreach ( $items as $item ) {
            $timestamp = false;
            $sort_key  = '';

            if ( 'dynamic' === $item['kind'] ) {
                $timestamp = strtotime( $item['pattern'] . ' ' . $year . ' 12:00:00' );
            } else {
                $timestamp = strtotime( $year . '-' . $item['date'] . ' 12:00:00' );
            }

            if ( false === $timestamp ) {
                continue;
            }

            $sort_key = gmdate( 'm-d', $timestamp );

            $rows[] = array(
                'timestamp'  => (int) $timestamp,
                'sort_key'   => $sort_key,
                'date_label' => wp_date( 'F j', $timestamp ),
                'title'      => $item['title'],
                'note'       => $item['note'],
            );
        }

        usort(
            $rows,
            static function ( $a, $b ) {
                return strcmp( (string) $a['sort_key'], (string) $b['sort_key'] );
            }
        );

        return $rows;
    }
}

if ( ! function_exists( 'noesia_swa_global_pulse_bool_label' ) ) {
    /**
     * Convert a boolean-like value into a label.
     *
     * @param bool $value Boolean state.
     * @return string
     */
    function noesia_swa_global_pulse_bool_label( $value ) {
        return $value ? __( 'Yes', 'noesia-smart-waiter' ) : __( 'No', 'noesia-smart-waiter' );
    }
}

if ( ! function_exists( 'noesia_swa_global_pulse_time_ago_label' ) ) {
    /**
     * Return a human time-ago label.
     *
     * @param int $timestamp Unix timestamp.
     * @return string
     */
    function noesia_swa_global_pulse_time_ago_label( $timestamp ) {
        $timestamp = absint( $timestamp );

        if ( $timestamp <= 0 ) {
            return __( 'No recent check recorded.', 'noesia-smart-waiter' );
        }

        $now = current_time( 'timestamp' );

        if ( $timestamp >= $now ) {
            return __( 'Just now', 'noesia-smart-waiter' );
        }

        /* translators: %s: human-readable time difference. */
        return sprintf( __( '%s ago', 'noesia-smart-waiter' ), human_time_diff( $timestamp, $now ) );
    }
}

if ( ! function_exists( 'noesia_swa_global_pulse_compact_names' ) ) {
    /**
     * Build a short comma-separated label list.
     *
     * @param array<int, string> $names Raw names.
     * @return string
     */
    function noesia_swa_global_pulse_compact_names( $names ) {
        $names = array_values(
            array_filter(
                array_map( 'sanitize_text_field', $names )
            )
        );

        if ( empty( $names ) ) {
            return '';
        }

        $max   = 4;
        $slice = array_slice( $names, 0, $max );
        $text  = implode( ', ', $slice );
        $extra = count( $names ) - count( $slice );

        if ( $extra > 0 ) {
            /* translators: %d: additional hidden items count. */
            $text .= ' +' . sprintf( __( '%d more', 'noesia-smart-waiter' ), $extra );
        }

        return $text;
    }
}

if ( ! function_exists( 'noesia_swa_global_pulse_get_update_snapshot' ) ) {
    /**
     * Build an update snapshot from existing WordPress update transients.
     *
     * @return array<string, mixed>
     */
    function noesia_swa_global_pulse_get_update_snapshot() {
        $core_transient    = get_site_transient( 'update_core' );
        $plugins_transient = get_site_transient( 'update_plugins' );
        $themes_transient  = get_site_transient( 'update_themes' );

        $core_count     = 0;
        $core_versions  = array();
        $core_checked   = 0;
        $plugins_count  = 0;
        $plugins_checked = 0;
        $plugin_names   = array();
        $themes_count   = 0;
        $themes_checked = 0;
        $theme_names    = array();
        $translations_count = 0;

        if ( is_object( $core_transient ) ) {
            $core_checked = isset( $core_transient->last_checked ) ? absint( $core_transient->last_checked ) : 0;

            if ( ! empty( $core_transient->updates ) && is_array( $core_transient->updates ) ) {
                foreach ( $core_transient->updates as $update_item ) {
                    if ( ! is_object( $update_item ) ) {
                        continue;
                    }

                    if ( isset( $update_item->response ) && 'upgrade' === $update_item->response ) {
                        ++$core_count;

                        if ( ! empty( $update_item->current ) ) {
                            $core_versions[] = sanitize_text_field( (string) $update_item->current );
                        }
                    }
                }
            }

            if ( ! empty( $core_transient->translations ) && is_array( $core_transient->translations ) ) {
                $translations_count += count( $core_transient->translations );
            }
        }

        if ( is_object( $plugins_transient ) ) {
            $plugins_checked = isset( $plugins_transient->last_checked ) ? absint( $plugins_transient->last_checked ) : 0;

            if ( ! empty( $plugins_transient->response ) && is_array( $plugins_transient->response ) ) {
                $plugins_count = count( $plugins_transient->response );

                if ( ! function_exists( 'get_plugins' ) ) {
                    require_once ABSPATH . 'wp-admin/includes/plugin.php';
                }

                $all_plugins = function_exists( 'get_plugins' ) ? get_plugins() : array();

                foreach ( array_keys( $plugins_transient->response ) as $plugin_file ) {
                    $plugin_file = sanitize_text_field( (string) $plugin_file );

                    if ( isset( $all_plugins[ $plugin_file ]['Name'] ) ) {
                        $plugin_names[] = sanitize_text_field( (string) $all_plugins[ $plugin_file ]['Name'] );
                    } else {
                        $plugin_names[] = sanitize_text_field( basename( $plugin_file ) );
                    }
                }
            }

            if ( ! empty( $plugins_transient->translations ) && is_array( $plugins_transient->translations ) ) {
                $translations_count += count( $plugins_transient->translations );
            }
        }

        if ( is_object( $themes_transient ) ) {
            $themes_checked = isset( $themes_transient->last_checked ) ? absint( $themes_transient->last_checked ) : 0;

            if ( ! empty( $themes_transient->response ) && is_array( $themes_transient->response ) ) {
                $themes_count = count( $themes_transient->response );

                foreach ( array_keys( $themes_transient->response ) as $stylesheet ) {
                    $stylesheet = sanitize_text_field( (string) $stylesheet );
                    $theme      = wp_get_theme( $stylesheet );

                    if ( $theme instanceof WP_Theme && $theme->exists() ) {
                        $theme_names[] = sanitize_text_field( (string) $theme->get( 'Name' ) );
                    } else {
                        $theme_names[] = $stylesheet;
                    }
                }
            }

            if ( ! empty( $themes_transient->translations ) && is_array( $themes_transient->translations ) ) {
                $translations_count += count( $themes_transient->translations );
            }
        }

        $groups = array(
            array(
                'title'        => __( 'WordPress Core', 'noesia-smart-waiter' ),
                'count'        => $core_count,
                'detail'       => ( $core_count > 0 && ! empty( $core_versions ) )
                    ? implode( ', ', array_unique( $core_versions ) )
                    : __( 'No newer core package detected in the latest check.', 'noesia-smart-waiter' ),
                'checked'      => $core_checked,
                'empty_detail' => __( 'Core is aligned with the latest recorded check.', 'noesia-smart-waiter' ),
            ),
            array(
                'title'        => __( 'Plugins', 'noesia-smart-waiter' ),
                'count'        => $plugins_count,
                'detail'       => noesia_swa_global_pulse_compact_names( $plugin_names ),
                'checked'      => $plugins_checked,
                'empty_detail' => __( 'No plugin updates are waiting right now.', 'noesia-smart-waiter' ),
            ),
            array(
                'title'        => __( 'Themes', 'noesia-smart-waiter' ),
                'count'        => $themes_count,
                'detail'       => noesia_swa_global_pulse_compact_names( $theme_names ),
                'checked'      => $themes_checked,
                'empty_detail' => __( 'No theme updates are waiting right now.', 'noesia-smart-waiter' ),
            ),
            array(
                'title'        => __( 'Translations', 'noesia-smart-waiter' ),
                'count'        => $translations_count,
                'detail'       => __( 'Language packs pending synchronization.', 'noesia-smart-waiter' ),
                'checked'      => max( $core_checked, $plugins_checked, $themes_checked ),
                'empty_detail' => __( 'Language packs are already synchronized.', 'noesia-smart-waiter' ),
            ),
        );

        return array(
            'pending_total' => $core_count + $plugins_count + $themes_count + $translations_count,
            'groups'        => $groups,
            'latest_check'  => max( $core_checked, $plugins_checked, $themes_checked ),
        );
    }
}

if ( ! class_exists( 'Noesia_SWA_Global_Pulse_Data' ) ) {
    /**
     * Global Pulse data helper.
     */
    class Noesia_SWA_Global_Pulse_Data {

        /**
         * Build the legacy Global Pulse view context.
         *
         * @return array<string, mixed>
         */
        public function get_context() {
            $current_timestamp = current_time( 'timestamp' );
            $current_year      = (int) wp_date( 'Y', $current_timestamp );
            $current_sort_key  = wp_date( 'm-d', $current_timestamp );
            $planet_days       = noesia_swa_global_pulse_get_planet_days( $current_year );
            $update_snapshot   = noesia_swa_global_pulse_get_update_snapshot();
            $pending_total     = isset( $update_snapshot['pending_total'] ) ? absint( $update_snapshot['pending_total'] ) : 0;
            $all_clear         = 0 === $pending_total;
            $next_planet_day   = null;

            foreach ( $planet_days as $planet_day ) {
                if ( ! isset( $planet_day['sort_key'] ) ) {
                    continue;
                }

                if ( (string) $planet_day['sort_key'] >= $current_sort_key ) {
                    $next_planet_day = $planet_day;
                    break;
                }
            }

            if ( null === $next_planet_day ) {
                $next_year_days = noesia_swa_global_pulse_get_planet_days( $current_year + 1 );
                if ( ! empty( $next_year_days ) ) {
                    $next_planet_day = $next_year_days[0];
                }
            }

            global $wpdb;

            $server_software = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( (string) $_SERVER['SERVER_SOFTWARE'] ) ) : __( 'Unknown', 'noesia-smart-waiter' );
            $timezone_string = wp_timezone_string();
            $timezone_label  = '' !== $timezone_string ? $timezone_string : __( 'UTC offset only', 'noesia-smart-waiter' );
            $theme           = wp_get_theme();
            $theme_name      = ( $theme instanceof WP_Theme && $theme->exists() ) ? sanitize_text_field( (string) $theme->get( 'Name' ) ) : __( 'Unknown', 'noesia-smart-waiter' );
            $active_plugins  = get_option( 'active_plugins', array() );
            $active_count    = is_array( $active_plugins ) ? count( $active_plugins ) : 0;
            $db_version      = ( is_object( $wpdb ) && method_exists( $wpdb, 'db_version' ) ) ? sanitize_text_field( (string) $wpdb->db_version() ) : __( 'Unknown', 'noesia-smart-waiter' );
            $php_limit       = ini_get( 'memory_limit' );
            $post_limit      = ini_get( 'post_max_size' );
            $upload_limit    = ini_get( 'upload_max_filesize' );
            $exec_limit      = ini_get( 'max_execution_time' );

            $server_rows = array(
                array(
                    'label' => __( 'WordPress Version', 'noesia-smart-waiter' ),
                    'value' => get_bloginfo( 'version' ),
                ),
                array(
                    'label' => __( 'PHP Version', 'noesia-smart-waiter' ),
                    'value' => PHP_VERSION,
                ),
                array(
                    'label' => __( 'Database Version', 'noesia-smart-waiter' ),
                    'value' => $db_version,
                ),
                array(
                    'label' => __( 'Web Server', 'noesia-smart-waiter' ),
                    'value' => $server_software,
                ),
                array(
                    'label' => __( 'Environment Type', 'noesia-smart-waiter' ),
                    'value' => wp_get_environment_type(),
                ),
                array(
                    'label' => __( 'Site Language', 'noesia-smart-waiter' ),
                    'value' => get_locale(),
                ),
                array(
                    'label' => __( 'Timezone', 'noesia-smart-waiter' ),
                    'value' => $timezone_label,
                ),
                array(
                    'label' => __( 'WP Memory Limit', 'noesia-smart-waiter' ),
                    'value' => defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : __( 'Not defined', 'noesia-smart-waiter' ),
                ),
                array(
                    'label' => __( 'PHP Memory Limit', 'noesia-smart-waiter' ),
                    'value' => ( false !== $php_limit && '' !== $php_limit ) ? (string) $php_limit : __( 'Unknown', 'noesia-smart-waiter' ),
                ),
                array(
                    'label' => __( 'Max Upload Size', 'noesia-smart-waiter' ),
                    'value' => size_format( wp_max_upload_size() ),
                ),
                array(
                    'label' => __( 'PHP Upload Limit', 'noesia-smart-waiter' ),
                    'value' => ( false !== $upload_limit && '' !== $upload_limit ) ? (string) $upload_limit : __( 'Unknown', 'noesia-smart-waiter' ),
                ),
                array(
                    'label' => __( 'Post Size Limit', 'noesia-smart-waiter' ),
                    'value' => ( false !== $post_limit && '' !== $post_limit ) ? (string) $post_limit : __( 'Unknown', 'noesia-smart-waiter' ),
                ),
                array(
                    'label' => __( 'Max Execution Time', 'noesia-smart-waiter' ),
                    'value' => ( false !== $exec_limit && '' !== $exec_limit ) ? (string) $exec_limit . 's' : __( 'Unknown', 'noesia-smart-waiter' ),
                ),
                array(
                    'label' => __( 'HTTPS Enabled', 'noesia-smart-waiter' ),
                    'value' => noesia_swa_global_pulse_bool_label( is_ssl() ),
                ),
                array(
                    'label' => __( 'Multisite', 'noesia-smart-waiter' ),
                    'value' => noesia_swa_global_pulse_bool_label( is_multisite() ),
                ),
                array(
                    'label' => __( 'Debug Mode', 'noesia-smart-waiter' ),
                    'value' => noesia_swa_global_pulse_bool_label( defined( 'WP_DEBUG' ) && WP_DEBUG ),
                ),
                array(
                    'label' => __( 'External Object Cache', 'noesia-smart-waiter' ),
                    'value' => noesia_swa_global_pulse_bool_label( wp_using_ext_object_cache() ),
                ),
                array(
                    'label' => __( 'WP-Cron Disabled', 'noesia-smart-waiter' ),
                    'value' => noesia_swa_global_pulse_bool_label( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
                ),
                array(
                    'label' => __( 'Active Theme', 'noesia-smart-waiter' ),
                    'value' => $theme_name,
                ),
                array(
                    'label' => __( 'Active Plugins', 'noesia-smart-waiter' ),
                    /* translators: %d: active plugin count. */
                    'value' => sprintf( __( '%d active', 'noesia-smart-waiter' ), $active_count ),
                ),
            );

            return array(
                'all_clear'       => $all_clear,
                'pending_total'   => $pending_total,
                'update_snapshot' => $update_snapshot,
                'next_planet_day' => $next_planet_day,
                'planet_days'     => $planet_days,
                'server_rows'     => $server_rows,
            );
        }
    }
}
