<?php
/**
 * LinkCentral Dashboard Widget Class
 *
 * This class handles the simplified analytics dashboard widget
 * for the main WordPress dashboard. It displays:
 * - Last 24 hours and last 7 days click statistics (total, and unique if enabled)
 * - Top 3 most popular links with click counts
 * - Link to full analytics page & add new link button
 * 
 * Optimized  for performance:
 * - Uses a single query to get all statistics and popular links.
 * - 15-minute caching to avoid expensive queries on every dashboard load
 * - Cache clears when links are created/updated
 */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class LinkCentral_Dashboard_Widget {
    /**
     * Cache duration in seconds (15 minutes).
     */
    const CACHE_DURATION = 15 * MINUTE_IN_SECONDS;

    /**
     * Default number of popular links to show.
     */
    const DEFAULT_POPULAR_LINKS_LIMIT = 3;

    /**
     * Constructor.
     */
    public function __construct() {
        // No dependencies needed
    }

    /**
     * Initialize the class and set up WordPress hooks.
     */
    public function init() {
        // Only set up hooks if user has permission to view stats
        if (!current_user_can('linkcentral_view_stats')) {
            return;
        }

        // Add dashboard widget
        add_action('wp_dashboard_setup', array($this, 'add_dashboard_widget'));

        // Enqueue styles for dashboard widget
        add_action('admin_enqueue_scripts', array($this, 'enqueue_dashboard_styles'));

        // Clear cache when links are created/updated
        add_action('save_post_linkcentral_link', 'LinkCentral_Dashboard_Widget::clear_dashboard_cache');
    }

    /**
     * Add the dashboard widget.
     */
    public function add_dashboard_widget() {
        wp_add_dashboard_widget(
            'linkcentral_analytics_widget',
            esc_html__( 'LinkCentral Analytics', 'linkcentral' ),
            array($this, 'render_dashboard_widget')
        );
    }

    /**
     * Clear dashboard widget cache.
     */
    public static function clear_dashboard_cache() {
        // Clear all possible cache combinations (unique tracking × period)
        $periods = array(7, 14, 30);
        foreach (array(0, 1) as $unique_tracking) {
            foreach ($periods as $period) {
                delete_transient('linkcentral_dashboard_widget_' . $unique_tracking . '_' . $period);
            }
        }
    }

    /**
     * Enqueue styles for the dashboard widget.
     */
    public function enqueue_dashboard_styles($hook) {
        // Only load on dashboard
        if ($hook === 'index.php') {
            wp_enqueue_style(
                'linkcentral-dashboard-widget',
                LINKCENTRAL_PLUGIN_URL . 'assets/css/dashboard-widget.css',
                array(),
                LINKCENTRAL_VERSION
            );
        }
    }

    /**
     * Render the dashboard widget content.
     */
    public function render_dashboard_widget() {
        $track_unique_visitors = get_option('linkcentral_track_unique_visitors', false);
        $period_days = (int) get_option('linkcentral_dashboard_widget_period', 7);

        // Try to get cached data first
        $cache_key = 'linkcentral_dashboard_widget_' . ($track_unique_visitors ? '1' : '0') . '_' . $period_days;
        $cached_data = get_transient($cache_key);

        if ($cached_data !== false) {
            $stats_24h = $cached_data['stats_24h'];
            $stats_period = $cached_data['stats_period'];
            $popular_links = $cached_data['popular_links'];
        } else {
            // Get fresh data and cache it
            $stats_data = $this->get_all_stats($track_unique_visitors);
            $stats_24h = $stats_data['24h'];
            $stats_period = $stats_data['period'];
            $popular_links = $this->get_popular_links(self::DEFAULT_POPULAR_LINKS_LIMIT, $period_days);

            // Cache for specified duration
            $cache_data = array(
                'stats_24h' => $stats_24h,
                'stats_period' => $stats_period,
                'popular_links' => $popular_links
            );
            set_transient($cache_key, $cache_data, self::CACHE_DURATION);
        }
        
        ?>
        <div class="linkcentral-dashboard-widget">
            <div class="linkcentral-stats-grid">
                <?php $this->render_stat_box( esc_html__( 'Last 24 Hours', 'linkcentral' ), $stats_24h, $track_unique_visitors ); ?>
                <?php /* translators: %d: number of days in the selected dashboard widget period. */ ?>
                <?php $this->render_stat_box( sprintf( _n( 'Last %d Day', 'Last %d Days', $stats_period['days'], 'linkcentral' ), $stats_period['days'] ), $stats_period, $track_unique_visitors ); ?>
            </div>
            
            <?php if (!empty($popular_links)): ?>
                <div class="linkcentral-popular-links">
                    <div class="linkcentral-section-header">
                        <?php /* translators: %d: number of days in the popular links reporting period. */ ?>
                        <h4><?php echo esc_html( sprintf( _n( 'Most Popular Links (Last %d Day)', 'Most Popular Links (Last %d Days)', $period_days, 'linkcentral' ), $period_days ) ); ?></h4>
                    </div>
                    <ul class="linkcentral-links-list">
                        <?php foreach ($popular_links as $link): ?>
                            <li class="linkcentral-link-item">
                                <div class="linkcentral-link-title">
                                    <?php if ( ! empty( $link['edit_link'] ) ) : ?>
                                        <a href="<?php echo esc_url( $link['edit_link'] ); ?>" target="_blank">
                                            <?php echo esc_html( $link['post_title'] ); ?>
                                        </a>
                                    <?php else : ?>
                                        <?php echo esc_html( $link['post_title'] ); ?>
                                    <?php endif; ?>
                                </div>
                                <div class="linkcentral-link-stats">
                                    <span class="linkcentral-click-count">
                                        <?php
                                        printf(
                                            /* translators: %s: formatted number of clicks. */
                                            esc_html( _n( '%s click', '%s clicks', $link['total_clicks'], 'linkcentral' ) ),
                                            esc_html( number_format_i18n( $link['total_clicks'] ) )
                                        );
                                        ?>
                                    </span>
                                </div>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            <?php else: ?>
                <div class="linkcentral-no-data">
                    <p><?php esc_html_e( 'No clicks recorded yet.', 'linkcentral' ); ?></p>
                </div>
            <?php endif; ?>

            <div class="linkcentral-widget-footer">
                <div class="linkcentral-footer-buttons">
                    <a href="<?php echo esc_url(admin_url('admin.php?page=linkcentral-insights')); ?>" class="button button-primary">
                        <?php esc_html_e( 'View Full Analytics', 'linkcentral' ); ?>
                    </a>
                    <a href="<?php echo esc_url(admin_url('post-new.php?post_type=linkcentral_link')); ?>" class="button button-secondary">
                        <span class="dashicons dashicons-plus-alt2"></span> <?php esc_html_e( 'Add New Link', 'linkcentral' ); ?>
                    </a>
                </div>
                <p class="linkcentral-cache-notice">
                    <em><?php esc_html_e( 'Data is refreshed every 15 minutes', 'linkcentral' ); ?></em>
                </p>
            </div>
        </div>
        <?php
    }

    /**
     * Render a statistics box.
     */
    private function render_stat_box($title, $stats, $track_unique_visitors) {
        ?>
        <div class="linkcentral-stat-box">
            <h4><?php echo esc_html($title); ?></h4>
            <div class="linkcentral-stat-row">
                <div class="linkcentral-stat-item">
                    <div class="linkcentral-stat-number"><?php echo esc_html( number_format_i18n( $stats['total_clicks'] ) ); ?></div>
                    <div class="linkcentral-stat-label"><?php esc_html_e( 'Total Clicks', 'linkcentral' ); ?></div>
                </div>
                <?php if ($track_unique_visitors): ?>
                    <div class="linkcentral-stat-item">
                        <div class="linkcentral-stat-number"><?php echo esc_html( number_format_i18n( $stats['unique_clicks'] ) ); ?></div>
                        <div class="linkcentral-stat-label"><?php esc_html_e( 'Unique Clicks', 'linkcentral' ); ?></div>
                    </div>
                <?php endif; ?>
            </div>
        </div>
        <?php
    }

    /**
     * Get all statistics in a single query.
     *
     * @param bool $track_unique_visitors Whether unique visitor tracking is enabled
     * @return array Statistics data for both periods
     */
    private function get_all_stats($track_unique_visitors) {
        global $wpdb;

        // Get the configured period for the dashboard widget (default to 7 days)
        $period_days = (int) get_option('linkcentral_dashboard_widget_period', 7);

        // Single query to get both 24h and configurable period stats
        $query = $wpdb->prepare(
            "SELECT
                SUM(CASE WHEN s.click_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN 1 ELSE 0 END) as clicks_24h,
                SUM(CASE WHEN s.click_date >= DATE_SUB(CURDATE(), INTERVAL %d DAY) THEN 1 ELSE 0 END) as clicks_period",
            $period_days
        );

        if ($track_unique_visitors) {
            $query .= $wpdb->prepare(
                ",
                    SUM(CASE WHEN s.click_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN s.first_click ELSE 0 END) as unique_24h,
                    SUM(CASE WHEN s.click_date >= DATE_SUB(CURDATE(), INTERVAL %d DAY) THEN s.first_click ELSE 0 END) as unique_period",
                $period_days
            );
        }

        $query .= " FROM {$wpdb->prefix}linkcentral_stats s";

        $results = $wpdb->get_row($query); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- query is built entirely from $wpdb->prepare() segments

        return array(
            '24h' => array(
                'total_clicks' => (int) ($results->clicks_24h ?? 0),
                'unique_clicks' => $track_unique_visitors ? (int) ($results->unique_24h ?? 0) : 0
            ),
            'period' => array(
                'total_clicks' => (int) ($results->clicks_period ?? 0),
                'unique_clicks' => $track_unique_visitors ? (int) ($results->unique_period ?? 0) : 0,
                'days' => $period_days
            )
        );
    }


    /**
     * Get popular links for the dashboard using single query.
     *
     * @param int $limit Number of links to return
     * @param int $period_days Number of days to look back (0 for all time)
     * @return array Popular links data
     */
    private function get_popular_links($limit = self::DEFAULT_POPULAR_LINKS_LIMIT, $period_days = 0) {
        global $wpdb;

        $track_unique_visitors = get_option('linkcentral_track_unique_visitors', false);

        // Query to get click counts for links with clicks
        $query = "SELECT
            s.link_id,
            COUNT(*) as total_clicks";

        if ($track_unique_visitors) {
            $query .= ", SUM(s.first_click) as unique_clicks";
        }

        $query .= " FROM {$wpdb->prefix}linkcentral_stats s WHERE 1=1";

        // Add date filter if period_days is specified
        if ($period_days > 0) {
            $query .= $wpdb->prepare(" AND s.click_date >= DATE_SUB(CURDATE(), INTERVAL %d DAY)", $period_days);
        }

        $query .= " GROUP BY s.link_id ORDER BY total_clicks DESC LIMIT %d";

        $click_counts = $wpdb->get_results($wpdb->prepare($query, $limit), OBJECT_K); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- $query is built from safe parts and passed directly to prepare()

        // Get corresponding posts
        if (!empty($click_counts)) {
            $link_ids = array_keys($click_counts);
            $posts = $wpdb->get_results($wpdb->prepare(
                "SELECT ID, post_title FROM {$wpdb->posts}
                 WHERE ID IN (" . implode(',', array_fill(0, count($link_ids), '%d')) . ")
                 AND post_type = 'linkcentral_link'
                 AND post_status IN ('publish', 'draft', 'private', 'trash')",
                $link_ids
            ), OBJECT_K);
        }

        // Format the results
        $formatted_results = array();
        foreach ($click_counts as $link_id => $stats) {
            $post = isset($posts[$link_id]) ? $posts[$link_id] : null;
            $formatted_results[] = array(
                'ID' => $link_id,
                'post_title' => $post ? ($post->post_title ?: __( 'Untitled Link', 'linkcentral' )) : __( 'Deleted Link', 'linkcentral' ),
                'total_clicks' => (int) $stats->total_clicks,
                'unique_clicks' => $track_unique_visitors ? (int) ($stats->unique_clicks ?? 0) : 0,
                'edit_link' => get_edit_post_link($link_id)
            );
        }

        return $formatted_results;
    }
}
