<?php

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

class List2Play_Servers_Shortcode {
    
    private $api;
    private $renderer;
    
    public function __construct($api, $renderer) {
        $this->api = $api;
        $this->renderer = $renderer;
        
        add_shortcode('list2play_servers', [$this, 'render']);
    }
    
    /**
     * Render shortcode
     */
    public function render($atts) {
        // Get default per_page from settings
        $default_per_page = get_option('list2play_default_per_page', 20);
        $default_style_preset = sanitize_key((string) get_option('list2play_default_style_preset', 'default'));
        if ($default_style_preset === '') {
            $default_style_preset = 'default';
        }
        
        $atts = shortcode_atts([
            'game_type' => '',
            'category' => '',
            'country' => '',
            'status' => '',
            'sort' => 'votes',
            'direction' => 'desc',
            'per_page' => (string) $default_per_page,
            'show_stats' => '', // Empty means use admin default
            'show_votes' => '', // Empty means use admin default
            'show_vote_button' => '', // Empty means use admin default
            'style_preset' => $default_style_preset,
        ], $atts, 'list2play_servers');
        
        // Shortcode always uses selected servers from admin settings
        // Get selected server IDs from admin settings
        $selected_ids = get_option('list2play_selected_server_ids', []);
        
        // Prepare API arguments
        $api_args = [];
        
        // Always use selected server IDs if available
        if (!empty($selected_ids) && is_array($selected_ids)) {
            $api_args['server_ids'] = $selected_ids;
        } else {
            // Fallback to user servers if no selection
            $api_args['user_servers_only'] = true;
        }
        
        // Apply filters
        if (!empty($atts['game_type'])) {
            $api_args['game_type'] = sanitize_text_field($atts['game_type']);
        }
        
        if (!empty($atts['category'])) {
            $api_args['category'] = sanitize_text_field($atts['category']);
        }
        
        if (!empty($atts['country'])) {
            $api_args['country'] = strtoupper(sanitize_text_field($atts['country']));
        }
        
        if (!empty($atts['status']) && in_array($atts['status'], ['online', 'offline'], true)) {
            $api_args['status'] = $atts['status'];
        }
        
        // Sorting
        if (!empty($atts['sort'])) {
            $api_args['sort'] = sanitize_text_field($atts['sort']);
        }
        
        if (!empty($atts['direction']) && in_array($atts['direction'], ['asc', 'desc'], true)) {
            $api_args['direction'] = $atts['direction'];
        }
        
        // Check if we have custom server order - if yes, we need to get ALL servers first, sort them, then apply pagination
        $server_order = get_option('list2play_server_order', []);
        $has_custom_order = !empty($server_order) && is_array($server_order) && count($server_order) > 0;
        
        // Get current page from URL parameter or default to 1
        // GET parameters don't require nonce verification, but we sanitize the input
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET parameters for pagination don't require nonce
        $current_page = isset($_GET['list2play_page']) ? absint(wp_unslash($_GET['list2play_page'])) : 1;
        if ($current_page < 1) {
            $current_page = 1;
        }
        
        // Pagination
        $per_page = absint($atts['per_page']);
        if ($per_page > 0 && $per_page <= 100) {
            $api_args['per_page'] = $per_page;
        }
        
        // Shortcode always uses selected servers from admin settings
        // Get selected server IDs from admin settings
        $selected_ids = get_option('list2play_selected_server_ids', []);
        $has_selected_ids = !empty($selected_ids) && is_array($selected_ids);
        
        // Always use selected IDs if available
        if ($has_selected_ids && !isset($api_args['server_ids'])) {
            $api_args['server_ids'] = $selected_ids;
        }
        
        // If we have custom order OR selected IDs, get ALL servers first, then sort/paginate
        if ($has_custom_order || $has_selected_ids) {
            // Get all servers without pagination
            $all_servers_args = $api_args;
            $all_servers_args['per_page'] = 1000; // Get a large number to get all servers
            unset($all_servers_args['page']);
            
            $all_response = $this->api->get_servers($all_servers_args);
            
            if (isset($all_response['error'])) {
                $error_message = $all_response['message'] ?? 'Failed to load servers';
                $status_code = $all_response['status_code'] ?? '';
                if ($status_code) {
                    $error_message .= ' (HTTP ' . $status_code . ')';
                }
                return '<div class="list2play-error" style="padding: 1rem; background: #fee; border: 1px solid #fcc; border-radius: 4px; color: #c33;">' . esc_html($error_message) . '</div>';
            }
            
            $all_servers = $all_response['data'] ?? [];
            
            // If we have selected IDs, check for missing servers and fetch them individually
            if ($has_selected_ids) {
                $returned_ids = array_map(function($server) {
                    return $server['id'] ?? 0;
                }, $all_servers);
                
                $missing_ids = array_diff($selected_ids, $returned_ids);
                
                foreach ($missing_ids as $server_id) {
                    $server_response = $this->api->get_server($server_id);
                    if (!isset($server_response['error']) && isset($server_response['id'])) {
                        $all_servers[] = $server_response;
                    }
                }
            }
            
            if (empty($all_servers)) {
                if ($has_selected_ids) {
                    return '<div class="list2play-empty" style="padding: 1rem; background: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; color: #666;">No servers found. Please select servers in the plugin settings.</div>';
                } else {
                    return '<div class="list2play-empty" style="padding: 1rem; background: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; color: #666;">No servers found. Please check your API token and server selection in the plugin settings.</div>';
                }
            }
            
            // Sort all servers by saved order if available
            if ($has_custom_order) {
                $order_map = array_flip($server_order);
                
                usort($all_servers, function($a, $b) use ($order_map) {
                    $order_a = isset($order_map[$a['id']]) ? $order_map[$a['id']] : 999999;
                    $order_b = isset($order_map[$b['id']]) ? $order_map[$b['id']] : 999999;
                    return $order_a - $order_b;
                });
            }
            
            // Apply pagination manually
            $total_servers = count($all_servers);
            $total_pages = ceil($total_servers / $per_page);
            $offset = ($current_page - 1) * $per_page;
            $paginated_servers = array_slice($all_servers, $offset, $per_page);
            
            // Build response with paginated data
            $response = [
                'data' => $paginated_servers,
                'pagination' => [
                    'current_page' => $current_page,
                    'last_page' => $total_pages,
                    'per_page' => $per_page,
                    'total' => $total_servers,
                ]
            ];
        } else {
            // No custom order and no selected IDs - use API pagination as normal
            $api_args['page'] = $current_page;
            
            // Get servers
            $response = $this->api->get_servers($api_args);
            
            if (isset($response['error'])) {
                $error_message = $response['message'] ?? 'Failed to load servers';
                $status_code = $response['status_code'] ?? '';
                if ($status_code) {
                    $error_message .= ' (HTTP ' . $status_code . ')';
                }
                return '<div class="list2play-error" style="padding: 1rem; background: #fee; border: 1px solid #fcc; border-radius: 4px; color: #c33;">' . esc_html($error_message) . '</div>';
            }
            
            if (!isset($response['data']) || empty($response['data'])) {
                return '<div class="list2play-empty" style="padding: 1rem; background: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; color: #666;">No servers found. Please check your API token and server selection in the plugin settings.</div>';
            }
        }
        
        // Render servers
        // Use admin settings as defaults if not specified in shortcode
        // Check if value is set AND not empty (empty string means use admin default)
        $show_stats = (!empty($atts['show_stats'])) ? filter_var($atts['show_stats'], FILTER_VALIDATE_BOOLEAN) : (get_option('list2play_show_stats', '1') === '1');
        $show_votes = (!empty($atts['show_votes'])) ? filter_var($atts['show_votes'], FILTER_VALIDATE_BOOLEAN) : (get_option('list2play_show_votes', '1') === '1');
        $show_vote_button = (!empty($atts['show_vote_button'])) ? filter_var($atts['show_vote_button'], FILTER_VALIDATE_BOOLEAN) : (get_option('list2play_show_vote_button', '1') === '1');
        
        // Get display options from settings (default: all true except chart)
        $display_options = [
            'show_hostname' => get_option('list2play_show_hostname', '1') === '1',
            'show_status' => get_option('list2play_show_status', '1') === '1',
            'show_address' => get_option('list2play_show_address', '1') === '1',
            'show_game' => get_option('list2play_show_game', '1') === '1',
            'show_region' => get_option('list2play_show_region', '1') === '1',
            'show_players' => get_option('list2play_show_players', '1') === '1',
            'show_map' => get_option('list2play_show_map', '1') === '1',
            'show_votes' => get_option('list2play_show_votes', '1') === '1',
            'show_chart' => get_option('list2play_show_chart', '0') === '1',
        ];
        
        return $this->renderer->render_server_list(
            $response['data'],
            [
                'show_stats' => $show_stats,
                'show_votes' => $show_votes,
                'show_vote_button' => $show_vote_button,
                'style_preset' => sanitize_key($atts['style_preset']),
                'display_options' => $display_options,
                'pagination' => $response['pagination'] ?? null,
            ]
        );
    }
}

