<?php
/**
 * Name: Storage Monitor (Dashboard Widget)
 * Description: Dashboard widget displaying disk space usage with visual breakdown by uploads, plugins, themes, and database size to monitor hosting storage limits and clean files
 * Category: Admin
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Hosting Limit Tracking",
 *     "description": "Monitor storage usage on shared hosting with 20GB limit to prevent site from breaking when disk space runs out."
 *   },
 *   {
 *     "title": "Database Growth Alerts",
 *     "description": "Track database size growth on WooCommerce sites to catch runaway logs or session tables before they impact performance."
 *   },
 *   {
 *     "title": "Media Library Management",
 *     "description": "See storage breakdown by uploads, database, and plugins to identify what's consuming space and plan cleanup efforts."
 *   }
 * ]
 * WhereToFind: {
 *   "location": "Dashboard Widget",
 *   "url": "admin.php",
 *   "instructions": "View the Storage Monitor widget on your admin dashboard",
 *   "newTab": false
 * }
 * Added: 2025-09-20
 * Tags: storage, disk, space, monitor, dashboard, widget
 */

// Prevent direct access
if (!defined('ABSPATH')) exit;

class SwitchboardStorageMonitor {
    
    public function __construct() {
        add_action('wp_dashboard_setup', [$this, 'add_dashboard_widget']);
    }
    
    public function add_dashboard_widget() {
        wp_add_dashboard_widget(
            'switchboard_storage_monitor',
            'Storage Monitor <span class="switchboard-badge">SWITCHBOARD</span>',
            [$this, 'render_widget']
        );
    }
    
    private function get_directory_size($path) {
        if (!is_dir($path)) {
            return 0;
        }

        $size = 0;
        try {
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::CATCH_GET_CHILD
            );

            foreach ($files as $file) {
                if (is_object($file) && $file->isFile()) {
                    $size += $file->getSize();
                }
            }
        } catch (Exception $e) {
            // Return 0 if there's an error reading the directory
            return 0;
        }

        return $size;
    }
    
    private function get_storage_data() {
        $transient_key = 'switchboard_storage_data';
        $cached = get_transient($transient_key);
        
        if ($cached !== false) {
            return $cached;
        }
        
        $wp_content = WP_CONTENT_DIR;
        
        $data = [
            'uploads' => $this->get_directory_size($wp_content . '/uploads'),
            'themes' => $this->get_directory_size($wp_content . '/themes'),
            'plugins' => $this->get_directory_size($wp_content . '/plugins'),
            'other' => 0
        ];
        
        $data['total'] = array_sum($data);
        
        // Cache for 1 hour
        set_transient($transient_key, $data, HOUR_IN_SECONDS);
        
        return $data;
    }
    
    public function render_widget() {
        $data = $this->get_storage_data();
        $total = $data['total'];

        if ($total === 0) {
            echo '<p>' . esc_html__('Unable to calculate storage usage.', 'wpswitchboard') . '</p>';
            return;
        }

        ?>
        <div style="margin: -12px -12px 0 -12px;">
            <div style="padding: 15px; background: #f6f7f7; border-bottom: 1px solid #c3c4c7;">
                <div style="font-size: 24px; font-weight: 600; color: #1d2327;">
                    <?php echo esc_html(size_format($total)); ?>
                </div>
                <div style="font-size: 13px; color: #646970;"><?php esc_html_e('Total Storage Used', 'wpswitchboard'); ?></div>
            </div>

            <div style="padding: 15px;">
                <?php
                $items = [
                    ['label' => esc_html__('Uploads', 'wpswitchboard'), 'size' => $data['uploads'], 'color' => '#2271b1'],
                    ['label' => esc_html__('Plugins', 'wpswitchboard'), 'size' => $data['plugins'], 'color' => '#00a32a'],
                    ['label' => esc_html__('Themes', 'wpswitchboard'), 'size' => $data['themes'], 'color' => '#f59e0b'],
                ];
                
                foreach ($items as $item):
                    $percentage = $total > 0 ? ($item['size'] / $total) * 100 : 0;
                ?>
                <div style="margin-bottom: 15px;">
                    <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                        <span style="font-size: 13px; font-weight: 500;"><?php echo esc_html($item['label']); ?></span>
                        <span style="font-size: 13px; color: #646970;"><?php echo esc_html(size_format($item['size'])); ?> (<?php echo esc_html(number_format($percentage, 1)); ?>%)</span>
                    </div>
                    <div style="height: 8px; background: #f0f0f1; border-radius: 4px; overflow: hidden;">
                        <div style="height: 100%; background: <?php echo esc_attr($item['color']); ?>; width: <?php echo esc_attr($percentage); ?>%; transition: width 0.3s;"></div>
                    </div>
                </div>
                <?php endforeach; ?>

                <div style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #f0f0f1; text-align: center;">
                    <button type="button" id="refresh-storage" class="button button-small"><?php esc_html_e('Refresh Data', 'wpswitchboard'); ?></button>
                </div>
            </div>
        </div>

        <script>
        jQuery(document).ready(function($) {
            $('#refresh-storage').on('click', function() {
                $(this).prop('disabled', true).text('<?php echo esc_js(__('Refreshing...', 'wpswitchboard')); ?>');

                $.post(ajaxurl, {
                    action: 'switchboard_refresh_storage',
                    nonce: '<?php echo esc_js(wp_create_nonce('refresh_storage')); ?>'
                }, function() {
                    location.reload();
                });
            });
        });
        </script>
        <?php
    }

    /**
     * Register data locations for cleanup system
     *
     * @return array
     */
    public function register_data_locations() {
        return [
            'options' => [],
            'option_patterns' => [
                '_transient_switchboard_storage_data',
                '_transient_timeout_switchboard_storage_data',
            ],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }
}

$switchboard_instance = new SwitchboardStorageMonitor();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);

// AJAX handler to refresh storage data
add_action('wp_ajax_switchboard_refresh_storage', function() {
    check_ajax_referer('refresh_storage', 'nonce');
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Unauthorized');
    }
    
    delete_transient('switchboard_storage_data');
    wp_send_json_success();
});
