<?php

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

class WPDD_File_Protection {
    
    public static function init() {
        add_action('template_redirect', array(__CLASS__, 'protect_direct_access'));
        add_filter('mod_rewrite_rules', array(__CLASS__, 'add_rewrite_rules'));
        add_action('init', array(__CLASS__, 'add_download_endpoint'));
    }
    
    public static function protect_direct_access() {
        $request_uri = $_SERVER['REQUEST_URI'];
        $upload_dir = wp_upload_dir();
        $protected_dir = '/' . WPDD_UPLOADS_DIR . '/';
        
        if (strpos($request_uri, $protected_dir) !== false) {
            wp_die(__('Direct access to this file is not allowed.', 'wp-digital-download'), 403);
        }
    }
    
    public static function add_rewrite_rules($rules) {
        $upload_dir = wp_upload_dir();
        $protected_path = str_replace(ABSPATH, '', $upload_dir['basedir']) . '/' . WPDD_UPLOADS_DIR;
        
        $new_rules = "# WP Digital Download Protection\n";
        $new_rules .= "<IfModule mod_rewrite.c>\n";
        $new_rules .= "RewriteRule ^" . $protected_path . "/.*$ - [F,L]\n";
        $new_rules .= "</IfModule>\n\n";
        
        return $new_rules . $rules;
    }
    
    public static function add_download_endpoint() {
        add_rewrite_endpoint('wpdd-download', EP_ROOT);
    }
    
    public static function move_to_protected_directory($attachment_id) {
        $upload_dir = wp_upload_dir();
        $protected_dir = trailingslashit($upload_dir['basedir']) . WPDD_UPLOADS_DIR;
        
        if (!file_exists($protected_dir)) {
            wp_mkdir_p($protected_dir);
            self::create_protection_files($protected_dir);
        }
        
        $file_path = get_attached_file($attachment_id);
        
        if (!file_exists($file_path)) {
            return false;
        }
        
        $filename = basename($file_path);
        $unique_filename = wp_unique_filename($protected_dir, $filename);
        $new_path = trailingslashit($protected_dir) . $unique_filename;
        
        if (copy($file_path, $new_path)) {
            $protected_url = trailingslashit($upload_dir['baseurl']) . WPDD_UPLOADS_DIR . '/' . $unique_filename;
            
            update_post_meta($attachment_id, '_wpdd_protected_file', $new_path);
            update_post_meta($attachment_id, '_wpdd_protected_url', $protected_url);
            
            return array(
                'path' => $new_path,
                'url' => $protected_url
            );
        }
        
        return false;
    }
    
    public static function create_protection_files($directory) {
        $htaccess_content = "Options -Indexes\n";
        $htaccess_content .= "deny from all\n";
        
        $htaccess_file = trailingslashit($directory) . '.htaccess';
        if (!file_exists($htaccess_file)) {
            file_put_contents($htaccess_file, $htaccess_content);
        }
        
        $index_content = "<?php\n// Silence is golden.\n";
        $index_file = trailingslashit($directory) . 'index.php';
        if (!file_exists($index_file)) {
            file_put_contents($index_file, $index_content);
        }
        
        $nginx_content = "location ~* ^/wp-content/uploads/" . WPDD_UPLOADS_DIR . " {\n";
        $nginx_content .= "    deny all;\n";
        $nginx_content .= "    return 403;\n";
        $nginx_content .= "}\n";
        
        $nginx_file = trailingslashit($directory) . 'nginx.conf';
        if (!file_exists($nginx_file)) {
            file_put_contents($nginx_file, $nginx_content);
        }
    }
    
    public static function get_protected_file_url($file_path) {
        $upload_dir = wp_upload_dir();
        $protected_dir = trailingslashit($upload_dir['basedir']) . WPDD_UPLOADS_DIR;
        
        if (strpos($file_path, $protected_dir) === 0) {
            $relative_path = str_replace($protected_dir, '', $file_path);
            return trailingslashit($upload_dir['baseurl']) . WPDD_UPLOADS_DIR . $relative_path;
        }
        
        return $file_path;
    }
    
    public static function is_protected_file($file_path) {
        $upload_dir = wp_upload_dir();
        $protected_dir = trailingslashit($upload_dir['basedir']) . WPDD_UPLOADS_DIR;
        
        return strpos($file_path, $protected_dir) === 0;
    }
    
    public static function generate_secure_download_url($file_path, $order_id, $expiry_hours = 24) {
        $token = wp_hash($file_path . $order_id . time());
        $expiry = time() + ($expiry_hours * 3600);
        
        set_transient('wpdd_download_' . $token, array(
            'file_path' => $file_path,
            'order_id' => $order_id,
            'expiry' => $expiry
        ), $expiry_hours * 3600);
        
        return add_query_arg(array(
            'wpdd_secure_download' => $token
        ), home_url());
    }
    
    public static function handle_secure_download() {
        if (!isset($_GET['wpdd_secure_download'])) {
            return;
        }
        
        $token = sanitize_text_field($_GET['wpdd_secure_download']);
        $data = get_transient('wpdd_download_' . $token);
        
        if (!$data) {
            wp_die(__('Invalid or expired download link.', 'wp-digital-download'));
        }
        
        if ($data['expiry'] < time()) {
            delete_transient('wpdd_download_' . $token);
            wp_die(__('This download link has expired.', 'wp-digital-download'));
        }
        
        if (!file_exists($data['file_path'])) {
            wp_die(__('File not found.', 'wp-digital-download'));
        }
        
        delete_transient('wpdd_download_' . $token);
        
        self::serve_download($data['file_path']);
    }
    
    private static function serve_download($file_path) {
        $file_name = basename($file_path);
        $file_size = filesize($file_path);
        $file_type = wp_check_filetype($file_path);
        
        nocache_headers();
        
        header('Content-Type: ' . ($file_type['type'] ?: 'application/octet-stream'));
        header('Content-Disposition: attachment; filename="' . $file_name . '"');
        header('Content-Length: ' . $file_size);
        header('Content-Transfer-Encoding: binary');
        
        if (ob_get_level()) {
            ob_end_clean();
        }
        
        readfile($file_path);
        exit;
    }
}