<?php
/*
 * Plugin Name: Cloud Uploads Pro
 * Description: Migrate and store your wordpress upload files remotely on cloud storage along with cdn for fast delivery.
 * Version: 2.0.2
 * Author: Brij Raj Singh
 * Text Domain: cloud-uploads-pro
 * Requires at least: 5.3
 * Requires PHP: 7.4
 * License: GPLv2
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Network: true
 *
*/

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

// Define plugin constants
define('CLOUD_UPLOADS_VERSION', '2.0.1');
define('CLOUD_UPLOADS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CLOUD_UPLOADS_PLUGIN_URL', plugin_dir_url(__FILE__));

// Load AWS SDK
function cloud_uploads_load_aws_sdk() {
    $aws_phar_path = CLOUD_UPLOADS_PLUGIN_DIR . 'vendor/aws.phar';
    $aws_autoload_path = CLOUD_UPLOADS_PLUGIN_DIR . 'vendor/aws/aws-sdk-php/src/Aws/functions.php';
    
    if (file_exists($aws_phar_path)) {
        // Load from PHAR archive
        require_once $aws_phar_path;
    } elseif (file_exists($aws_autoload_path)) {
        // Load from extracted SDK
        require_once CLOUD_UPLOADS_PLUGIN_DIR . 'vendor/aws/aws-sdk-php/src/Aws/functions.php';
    } else {
        // Fallback to WordPress HTTP implementation
        add_action('admin_notices', function() {
            echo '<div class="notice notice-warning"><p>';
            echo 'Cloud Uploads: AWS SDK not found. Using WordPress HTTP fallback for S3 operations.';
            echo '</p></div>';
        });
        return false;
    }
    
    return true;
}

// Initialize AWS SDK
// if (!cloud_uploads_load_aws_sdk()) {
//     // Continue with fallback implementation
// }

// Include required files
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-s3-client.php';
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-s3-sync.php';
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-url-rewriter.php';
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-bulk-sync.php';
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-settings.php';
require_once CLOUD_UPLOADS_PLUGIN_DIR . 'includes/class-resource-checker.php';

// Initialize the plugin
class Cloud_Uploads_Plugin {
    
    private $s3_client;
    private $s3_sync;
    private $url_rewriter;
    private $bulk_sync;
    private $settings;
    
    public function __construct() {
        add_action('plugins_loaded', array($this, 'init'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
        add_action('wp_ajax_cloud_uploads_batch', array($this, 'ajax_batch_sync'));
        add_action('wp_ajax_cloud_uploads_get_stats', array($this, 'ajax_get_sync_stats'));
        
        // Add upload hooks to catch all upload methods
        add_filter('wp_handle_upload_prefilter', array($this, 'handle_upload_prefilter'));
        add_filter('wp_handle_upload', array($this, 'handle_upload'));

        // Add cron hooks for deferred processing
        add_action('cloud_uploads_process_deferred', array($this, 'process_deferred_syncs'));
        add_action('cloud_uploads_process_sizes', array($this, 'process_deferred_sizes'));
        
        // Add custom cron schedule
        add_filter('cron_schedules', array($this, 'add_cron_schedules'));

        add_action('wp_ajax_cloud_uploads_test_connection', array($this, 'ajax_test_connection'));

        add_action('wp_ajax_cloud_uploads_check_status', array($this, 'ajax_check_sync_status'));

        add_action('wp_ajax_cloud_uploads_test_upload', array($this, 'ajax_test_upload'));

        register_activation_hook(__FILE__, array($this, 'activate'));
        register_deactivation_hook(__FILE__, array($this, 'deactivate'));
        
        // Debug logging
        if (defined('WP_DEBUG') && WP_DEBUG) {
            add_action('cloud_uploads_after_upload', array($this, 'log_upload'), 10, 2);
            add_action('cloud_uploads_error', array($this, 'log_error'), 10, 2);
        }
    }

    public function ajax_test_connection() {
        check_ajax_referer('cloud_uploads_test_connection', 'nonce');
    
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Unauthorized'));
        }
        
        // Check if S3 client is initialized
        if (!$this->s3_client) {
            wp_send_json_error(array('message' => 'S3 client not initialized. Please check your settings.'));
        }
        
        // Test the connection
        $result = $this->s3_client->test_connection();
        
        if ($result['success']) {
            wp_send_json_success(array('message' => $result['message']));
        } else {
            wp_send_json_error(array('message' => $result['message']));
        }
    }

    // Add this to your main plugin file or Cloud_Uploads_Plugin class
    public function ajax_test_upload() {
        check_ajax_referer('cloud_uploads_test', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Unauthorized');
        }
        
        if (empty($_FILES['file'])) {
            wp_send_json_error('No file uploaded');
        }
        
        // Check if S3 client is initialized
        if (!$this->s3_client) {
            wp_send_json_error('S3 client not initialized. Please check your settings.');
        }
        
        // Upload the test file to S3
        $file = $_FILES['file'];
        $upload_dir = wp_upload_dir();
        $file_path = $upload_dir['path'] . '/' . basename($file['name']);
        
        if (!move_uploaded_file($file['tmp_name'], $file_path)) {
            wp_send_json_error('Could not move uploaded file to: ' . $file_path);
        }
        
        // Try to upload to S3
        try {
            $relative_path = str_replace($upload_dir['basedir'] . '/', '', $file_path);
            $path_prefix = $this->settings->get_option('path_prefix');
            $s3_path = !empty($path_prefix) ? $path_prefix . $relative_path : $relative_path;
            
            $result = $this->s3_client->upload_file($file_path, $s3_path);
            
            // Clean up local file
            if (file_exists($file_path)) {
                unlink($file_path);
            }
            
            if ($result) {
                wp_send_json_success(array(
                    'message' => 'File successfully uploaded to S3',
                    's3_url' => $result,
                    's3_path' => $s3_path
                ));
            } else {
                wp_send_json_error('Failed to upload file to S3. Check your credentials and permissions.');
            }
        } catch (Exception $e) {
            // Clean up local file
            if (file_exists($file_path)) {
                unlink($file_path);
            }
            
            wp_send_json_error('Cloud Uploads error: ' . $e->getMessage());
        }
    }

    
    /**
     * Handle upload prefilter
     */
    public function handle_upload_prefilter($file) {
        // This runs before the file is processed
        // We can use this to log the upload process
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('Cloud Uploads: Handling upload prefilter for: ' . $file['name']);
        }
        return $file;
    }

    /**
     * Handle upload after file is processed
     */
    public function handle_upload($fileinfo) {
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('Cloud Uploads: Handling upload for: ' . $fileinfo['file']);
        }
        
        // If S3 sync is configured, try to sync the file
        if ($this->s3_sync && !empty($fileinfo['file'])) {
            // Try to find the attachment ID
            $attachment_id = $this->s3_sync->get_attachment_id_from_file($fileinfo['file']);
            
            if ($attachment_id) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('Cloud Uploads: Found attachment ID: ' . $attachment_id . ' for file: ' . $fileinfo['file']);
                }
                
                // Sync to S3
                $result = $this->s3_sync->sync_attachment($attachment_id);
                
                if ($result) {
                    if (defined('WP_DEBUG') && WP_DEBUG) {
                        error_log('Cloud Uploads Plugin: Successfully synced attachment: ' . $attachment_id);
                    }
                } else {
                    if (defined('WP_DEBUG') && WP_DEBUG) {
                        error_log('Cloud Uploads Plugin: Failed to sync attachment: ' . $attachment_id);
                    }
                }
            } else {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('Cloud Uploads Plugin: Could not find attachment ID for file: ' . $fileinfo['file']);
                }
            }
        }
        
        return $fileinfo;
    }

    public function ajax_check_sync_status() {
        check_ajax_referer('cloud_uploads_nonce', 'nonce');
        
        if (!current_user_can('upload_files')) {
            wp_send_json_error('Unauthorized');
        }
        
        $attachment_id = isset($_POST['attachment_id']) ? intval($_POST['attachment_id']) : 0;
        
        if (!$attachment_id) {
            wp_send_json_error('Invalid attachment ID');
        }
        
        $synced = get_post_meta($attachment_id, '_s3_synced', true);
        $s3_url = get_post_meta($attachment_id, '_s3_url', true);
        
        wp_send_json_success(array(
            'synced' => (bool) $synced,
            's3_url' => $s3_url,
            'attachment_id' => $attachment_id
        ));
    }

    /**
     * Add custom cron schedules
     */
    public function add_cron_schedules($schedules) {
        $schedules['five_minutes'] = array(
            'interval' => 300, // 5 minutes
            'display' => __('Every 5 Minutes')
        );
        
        return $schedules;
    }

    /**
     * Process deferred syncs
     */
    public function process_deferred_syncs() {
        if ($this->s3_sync) {
            $this->s3_sync->process_deferred_syncs();
        }
    }

    /**
     * Process deferred sizes syncs
     */
    public function process_deferred_sizes() {
        if ($this->s3_sync) {
            $this->s3_sync->process_deferred_sizes();
        }
    }

    public function init() {
        $this->settings = new Cloud_Uploads_Settings();
        
        // Only initialize if settings are configured
        if ($this->settings->is_configured()) {
            $this->s3_client = new Cloud_Uploads_Client($this->settings);
            $this->s3_sync = new Cloud_Uploads($this->s3_client, $this->settings);
            $this->url_rewriter = new S3_URL_Rewriter($this->settings);
            $this->bulk_sync = new Bulk_Sync_Manager($this->s3_sync);
        }
        
        // Load text domain
        load_plugin_textdomain('cloud-uploads', false, dirname(plugin_basename(__FILE__)) . '/languages');
    }
    
    public function enqueue_admin_assets($hook) {
        if ($hook === 'media_page_cloud-uploads') {
            wp_enqueue_style('cloud-uploads-admin', CLOUD_UPLOADS_PLUGIN_URL . 'assets/css/admin.css', array(), CLOUD_UPLOADS_VERSION);
            wp_enqueue_script('cloud-uploads-admin', CLOUD_UPLOADS_PLUGIN_URL . 'assets/js/admin.js', array('jquery'), CLOUD_UPLOADS_VERSION, true);
            wp_enqueue_script('cloud-uploads-admin', CLOUD_UPLOADS_PLUGIN_URL . 'assets/js/debug.js', array('jquery'), CLOUD_UPLOADS_VERSION, true);
            wp_enqueue_script('cloud-uploads-admin', CLOUD_UPLOADS_PLUGIN_URL . 'assets/js/upload-debug.js', array('jquery'), CLOUD_UPLOADS_VERSION, true);
            
            // Localize script for AJAX
            wp_localize_script('cloud-uploads-admin', 'cloud_uploads_vars', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('cloud_uploads_nonce'),
                'batch_size' => apply_filters('cloud_uploads_batch_size', 5),
                'text_processing' => __('Processing...', 'cloud-uploads'),
                'text_completed' => __('Completed!', 'cloud-uploads'),
                'text_error' => __('Error occurred', 'cloud-uploads')
            ));
        }
        
        // Add debug script in debug mode
        if (defined('WP_DEBUG') && WP_DEBUG && $hook === 'upload.php') {
            wp_enqueue_script('cloud-uploads-debug', CLOUD_UPLOADS_PLUGIN_URL . 'assets/js/debug.js', array('jquery'), CLOUD_UPLOADS_VERSION, true);
        }
    }
    
    public function ajax_batch_sync() {
        check_ajax_referer('cloud_uploads_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }
        
        $batch = isset($_POST['batch']) ? intval($_POST['batch']) : 0;
        $batch_size = isset($_POST['batch_size']) ? intval($_POST['batch_size']) : 5;
        
        $result = $this->bulk_sync->process_batch($batch, $batch_size);
        
        wp_send_json_success($result);
    }
    
    public function ajax_get_sync_stats() {
        check_ajax_referer('cloud_uploads_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }
        
        $stats = $this->bulk_sync->get_sync_stats();
        
        wp_send_json_success($stats);
    }
    
    public function log_upload($attachment_id, $s3_path) {
        error_log('Cloud Uploads: Successfully uploaded attachment ' . $attachment_id . ' to ' . $s3_path);
    }
    
    public function log_error($attachment_id, $error_message) {
        error_log('Cloud Uploads: Failed to upload attachment ' . $attachment_id . ' - ' . $error_message);
    }
    
    public function activate() {
        // Set default options
        $default_options = array(
            'region' => 'us-east-1',
            'path_prefix' => 'uploads/',
            'delete_remote' => 1,
            'rewrite_urls' => 1
        );
        
        if (!get_option('cloud_uploads_options')) {
            add_option('cloud_uploads_options', $default_options);
        }
        
        // Create database table for sync progress if needed
        $this->create_sync_tables();
    }
    
    private function create_sync_tables() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 's3_sync_progress';
        $charset_collate = $wpdb->get_charset_collate();
        
        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            attachment_id bigint(20) NOT NULL,
            status varchar(20) NOT NULL DEFAULT 'pending',
            attempts smallint(3) NOT NULL DEFAULT 0,
            last_attempt datetime DEFAULT NULL,
            error_message text,
            PRIMARY KEY (id),
            KEY attachment_id (attachment_id),
            KEY status (status)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
    
    public function deactivate() {
        // Cleanup if needed
        // Clean up cron jobs
        wp_clear_scheduled_hook('cloud_uploads_process_deferred');
        wp_clear_scheduled_hook('cloud_uploads_process_sizes');
    }
}

// Initialize the plugin
new Cloud_Uploads_Plugin();