<?php

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

class List2Play_Servers_Renderer {
    
    private $api;
    
    public function __construct($api = null) {
        $this->api = $api;
    }
    
    public function set_api($api) {
        $this->api = $api;
    }

    private function get_style_preset(string $preset): array {
        $presets = [
            'default' => [
                'card_bg' => 'rgba(2, 6, 23, 0.7)',
                'card_border' => 'rgba(30, 41, 59, 1)',
                'text_primary' => '#ffffff',
                'text_muted' => '#94a3b8',
                'accent' => '#34d399',
                'status_online' => 'border border-emerald-500/30 bg-emerald-500/15 text-emerald-300',
                'status_offline' => 'border border-rose-500/30 bg-rose-500/15 text-rose-300',
                'chip_bg' => 'rgba(15, 23, 42, 0.7)',
                'chip_border' => 'rgba(51, 65, 85, 0.7)',
                'chip_text' => '#e2e8f0',
                'chart_line' => 'rgb(16, 185, 129)',
                'chart_area' => 'rgba(16, 185, 129, 0.10)',
                'chart_axis' => 'rgb(148, 163, 184)',
                'chart_grid' => 'rgba(148, 163, 184, 0.2)',
            ],
            'neon-cyan' => [
                'card_bg' => 'linear-gradient(135deg, #071521 0%, #0b1026 52%, #031923 100%)',
                'card_border' => '#22d3ee',
                'text_primary' => '#e6fdff',
                'text_muted' => '#67e8f9',
                'accent' => '#22d3ee',
                'status_online' => 'border border-cyan-300/50 bg-cyan-400/20 text-cyan-200',
                'status_offline' => 'border border-rose-300/40 bg-rose-500/20 text-rose-200',
                'chip_bg' => 'rgba(3, 25, 35, 0.7)',
                'chip_border' => 'rgba(34, 211, 238, 0.45)',
                'chip_text' => '#d8fbff',
                'chart_line' => 'rgb(34, 211, 238)',
                'chart_area' => 'rgba(34, 211, 238, 0.16)',
                'chart_axis' => 'rgb(103, 232, 249)',
                'chart_grid' => 'rgba(103, 232, 249, 0.22)',
            ],
            'neon-purple' => [
                'card_bg' => 'linear-gradient(135deg, #170b2a 0%, #130a23 45%, #09041a 100%)',
                'card_border' => '#a78bfa',
                'text_primary' => '#f3ecff',
                'text_muted' => '#c4b5fd',
                'accent' => '#a78bfa',
                'status_online' => 'border border-violet-300/50 bg-violet-500/20 text-violet-200',
                'status_offline' => 'border border-rose-300/40 bg-rose-500/20 text-rose-200',
                'chip_bg' => 'rgba(9, 4, 26, 0.7)',
                'chip_border' => 'rgba(167, 139, 250, 0.45)',
                'chip_text' => '#f1e8ff',
                'chart_line' => 'rgb(167, 139, 250)',
                'chart_area' => 'rgba(167, 139, 250, 0.16)',
                'chart_axis' => 'rgb(196, 181, 253)',
                'chart_grid' => 'rgba(196, 181, 253, 0.22)',
            ],
            'neon-red' => [
                'card_bg' => 'linear-gradient(135deg, #2b0a13 0%, #1f0c12 50%, #12080d 100%)',
                'card_border' => '#fb7185',
                'text_primary' => '#ffe9ef',
                'text_muted' => '#fda4af',
                'accent' => '#fb7185',
                'status_online' => 'border border-rose-300/50 bg-rose-500/20 text-rose-200',
                'status_offline' => 'border border-red-300/50 bg-red-500/20 text-red-200',
                'chip_bg' => 'rgba(18, 8, 13, 0.72)',
                'chip_border' => 'rgba(251, 113, 133, 0.45)',
                'chip_text' => '#ffe4ea',
                'chart_line' => 'rgb(251, 113, 133)',
                'chart_area' => 'rgba(251, 113, 133, 0.16)',
                'chart_axis' => 'rgb(253, 164, 175)',
                'chart_grid' => 'rgba(253, 164, 175, 0.22)',
            ],
            'neon-toxic' => [
                'card_bg' => 'linear-gradient(135deg, #121f06 0%, #0e1708 50%, #0a1207 100%)',
                'card_border' => '#a3e635',
                'text_primary' => '#f4ffe6',
                'text_muted' => '#bef264',
                'accent' => '#a3e635',
                'status_online' => 'border border-lime-300/50 bg-lime-500/20 text-lime-200',
                'status_offline' => 'border border-rose-300/40 bg-rose-500/20 text-rose-200',
                'chip_bg' => 'rgba(10, 18, 7, 0.74)',
                'chip_border' => 'rgba(163, 230, 53, 0.45)',
                'chip_text' => '#f3ffe1',
                'chart_line' => 'rgb(163, 230, 53)',
                'chart_area' => 'rgba(163, 230, 53, 0.16)',
                'chart_axis' => 'rgb(190, 242, 100)',
                'chart_grid' => 'rgba(190, 242, 100, 0.24)',
            ],
        ];

        return $presets[$preset] ?? $presets['default'];
    }
    
    /**
     * Get local game icon URL if available, otherwise return original URL
     * 
     * @param string $icon_url Original icon URL from API
     * @return string Local icon URL or original URL as fallback
     */
    private function get_local_game_icon_url($icon_url) {
        if (empty($icon_url)) {
            return '';
        }
        
        // Extract filename from URL (e.g., https://list2play.net/game-icons/minecraft.png -> minecraft.png)
        $filename = basename($icon_url);
        
        // Check if local file exists
        $local_path = LIST2PLAY_SERVERS_PLUGIN_DIR . 'public/assets/game-icons/' . $filename;
        if (file_exists($local_path)) {
            // Return local plugin URL
            return LIST2PLAY_SERVERS_PLUGIN_URL . 'public/assets/game-icons/' . $filename;
        }
        
        // Fallback to original URL if local file doesn't exist
        return $icon_url;
    }
    
    /**
     * Render server list
     */
    public function render_server_list($servers, $args = []) {
        $show_stats = $args['show_stats'] ?? true;
        $show_votes = $args['show_votes'] ?? true;
        $show_vote_button = $args['show_vote_button'] ?? true;
        $style_preset = sanitize_key($args['style_preset'] ?? 'default');
        $display_options = $args['display_options'] ?? [];
        $pagination = $args['pagination'] ?? null;
        
        $output = '<div class="list2play-servers-container">';
        
        // Mobile card design - visible everywhere (mobile and desktop)
        $output .= '<div class="list2play-servers-mobile">';
        foreach ($servers as $server) {
            $output .= $this->render_server_card_mobile($server, [
                'show_stats' => $show_stats,
                'show_votes' => $show_votes,
                'show_vote_button' => $show_vote_button,
                'style_preset' => $style_preset,
                'display_options' => $display_options,
            ]);
        }
        $output .= '</div>';
        
        $output .= '</div>';
        
        // Add pagination if available
        if ($pagination && $pagination['last_page'] > 1) {
            $output .= $this->render_pagination($pagination);
        }
        
        return $output;
    }
    
    /**
     * Render server card for mobile
     */
    private function render_server_card_mobile($server, $args = []) {
        $display_options = $args['display_options'] ?? [];
        
        // Default all to true if not set
        $show_hostname = $display_options['show_hostname'] ?? true;
        $show_status = $display_options['show_status'] ?? true;
        $show_address = $display_options['show_address'] ?? true;
        $show_game = $display_options['show_game'] ?? true;
        $show_region = $display_options['show_region'] ?? true;
        $show_players = $display_options['show_players'] ?? true;
        $show_map = $display_options['show_map'] ?? true;
        // Note: show_votes and show_vote_button are passed via $args, not display_options
        $style = $this->get_style_preset(sanitize_key($args['style_preset'] ?? 'default'));
        
        $is_online = $server['status'] === 'online';
        $status_classes = $is_online
            ? $style['status_online']
            : $style['status_offline'];
        
        $card_classes = 'mb-3 rounded-xl p-4 shadow-sm last:mb-0 border';
        
        $output = '<div class="' . esc_attr($card_classes) . '" style="background:' . esc_attr($style['card_bg']) . '; border-color:' . esc_attr($style['card_border']) . ';">';
        
        // Header with server name and status
        $output .= '<div class="flex items-start justify-between gap-3">';
        $output .= '<div class="min-w-0 flex-1">';
        if ($show_hostname) {
            $output .= '<a href="' . esc_url($server['url'] ?? '#') . '" class="flex items-center gap-2 truncate text-base font-semibold" style="color:' . esc_attr($style['text_primary']) . ';">';
            $output .= '<span class="truncate">' . esc_html($server['hostname'] ?? '') . '</span>';
            $output .= '</a>';
        }
        $output .= '</div>';
        if ($show_status) {
            $output .= '<span class="inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ' . esc_attr($status_classes) . '">';
            $output .= esc_html(ucfirst($server['status'] ?? 'unknown'));
            $output .= '</span>';
        }
        $output .= '</div>';
        
        // Server details
        $output .= '<div class="mt-3 space-y-2 text-xs" style="color:' . esc_attr($style['text_primary']) . ';">';
        
        // Check if Discord server
        $is_discord = !empty($server['game_type']['slug']) && $server['game_type']['slug'] === 'discord';
        
        // Address
        if ($show_address && !empty($server['display_address'])) {
            $output .= '<div class="flex flex-wrap items-center gap-2">';
            $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">' . esc_html($is_discord ? 'Join Link:' : 'Address:') . '</span>';
            if ($is_discord) {
                // Discord server - show link instead of copy button
                $discord_url = !empty($server['discord_invite_url']) ? $server['discord_invite_url'] : $server['display_address'];
                $output .= '<a href="' . esc_url($discord_url) . '" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';color:' . esc_attr($style['chip_text']) . ';" title="Join Discord server">';
                $output .= '<svg xmlns="http://www.w3.org/2000/svg" style="height: 0.75rem; width: 0.75rem;" fill="none" viewBox="0 0 24 24" stroke="currentColor">';
                $output .= '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />';
                $output .= '</svg>';
                $output .= esc_html($server['display_address']);
                $output .= '</a>';
            } else {
                // Regular server - show copy button
                $output .= '<button type="button" data-copy="' . esc_attr($server['display_address']) . '" class="inline-flex items-center gap-1 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';color:' . esc_attr($style['chip_text']) . ';" title="Copy address">';
                $output .= '<svg xmlns="http://www.w3.org/2000/svg" style="height: 0.75rem; width: 0.75rem;" fill="none" viewBox="0 0 24 24" stroke="currentColor">';
                $output .= '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 7v-2a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-2M9 7h-2a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2v-2M9 7h4.5a1.5 1.5 0 0 1 1.5 1.5V13" />';
                $output .= '</svg>';
                $output .= esc_html($server['display_address']);
                $output .= '</button>';
            }
            $output .= '</div>';
        }
        
        // Game type with icon
        if ($show_game && !empty($server['game_type'])) {
            $output .= '<div class="flex flex-wrap items-center gap-2">';
            $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">Game:</span>';
            $output .= '<span class="list2play-game-badge inline-flex items-center gap-2 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';color:' . esc_attr($style['accent']) . ';">';
            if (!empty($server['game_type']['icon_url'])) {
                $icon_url = $this->get_local_game_icon_url($server['game_type']['icon_url']);
                $output .= '<img src="' . esc_url($icon_url) . '" alt="' . esc_attr($server['game_type']['name'] ?? '') . ' icon" style="height: 1rem; width: 1rem; flex-shrink: 0; object-fit: contain;">';
            }
            $output .= '<span style="color:' . esc_attr($style['accent']) . '; white-space: nowrap;">' . esc_html($server['game_type']['name'] ?? '') . '</span>';
            $output .= '</span>';
            $output .= '</div>';
        }
        
        // Country flag
        if ($show_region && !empty($server['country_code'])) {
            $output .= '<div class="flex flex-wrap items-center gap-2">';
            $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">Region:</span>';
            $output .= '<span class="inline-flex items-center gap-2 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';">';
            $output .= '<span class="fi fi-' . esc_attr(strtolower($server['country_code'])) . ' fio rounded-sm"></span>';
            $output .= '<span style="color:' . esc_attr($style['chip_text']) . ';">' . esc_html(strtoupper($server['country_code'])) . '</span>';
            $output .= '</span>';
            $output .= '</div>';
        }
        
        // Players / Users
        if ($show_players && isset($server['current_players'])) {
            $output .= '<div class="flex flex-wrap items-center gap-2">';
            $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">' . esc_html($is_discord ? 'Users:' : 'Players:') . '</span>';
            $output .= '<span class="inline-flex items-center gap-2 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';color:' . esc_attr($style['chip_text']) . ';">';
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="currentColor" viewBox="0 0 24 24">';
            $output .= '<path d="M12 12a4 4 0 1 0-4-4 4 4 0 0 0 4 4Zm-2 1a5.99 5.99 0 0 0-6 6 1 1 0 0 0 1 1h14a1 1 0 0 0 1-1 5.99 5.99 0 0 0-6-6Z"/>';
            $output .= '</svg>';
            $output .= '<span>' . esc_html($server['current_players']);
            if (!empty($server['max_players']) && !$is_discord) {
                $output .= ' / ' . esc_html($server['max_players']);
            }
            $output .= '</span>';
            $output .= '</span>';
            $output .= '</div>';
        }
        
        // Map
        if ($show_map && !empty($server['current_map'])) {
            $output .= '<div class="flex flex-wrap items-center gap-2">';
            $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">Map:</span>';
            $output .= '<span class="inline-flex items-center gap-2 rounded-md border px-2 py-1" style="border-color:' . esc_attr($style['chip_border']) . ';background:' . esc_attr($style['chip_bg']) . ';color:' . esc_attr($style['chip_text']) . ';">';
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="currentColor" viewBox="0 0 24 24">';
            $output .= '<path d="m15.5 5.56-7-2a1 1 0 0 0-.63 0l-6 2A1 1 0 0 0 1 6.5v13a1 1 0 0 0 1.32.95L8 18.8l7 2a1 1 0 0 0 .63 0l6-2a1 1 0 0 0 .37-.23.998.998 0 0 0 .3-.72v-13a1 1 0 0 0-1.32-.95ZM9 5.28l6 1.72v11.72l-6-1.72Zm-2 .39v11.73l-4 1.15V6.83Zm14 11.15-4 1.15V6.15l4-1.15Z"/>';
            $output .= '</svg>';
            $output .= '<span>' . esc_html($server['current_map']) . '</span>';
            $output .= '</span>';
            $output .= '</div>';
        }
        
        // Server Stats section
        if ($args['show_stats']) {
            $stats_items = [];
            
            // Server ID
            if (!empty($server['id'])) {
                $stats_items[] = [
                    'label' => 'Server ID',
                    'value' => '#' . esc_html($server['id']),
                ];
            }
            
            // Last queried time
            if (!empty($server['last_queried_at'])) {
                $last_queried = strtotime($server['last_queried_at']);
                $time_ago = human_time_diff($last_queried, current_time('timestamp'));
                $stats_items[] = [
                    'label' => 'Last Update',
                    'value' => esc_html($time_ago . ' ago'),
                ];
            }
            
            // Submitted date
            if (!empty($server['submitted_at'])) {
                $submitted = strtotime($server['submitted_at']);
                $stats_items[] = [
                    'label' => 'Added',
                    'value' => esc_html(date_i18n(get_option('date_format'), $submitted)),
                ];
            }
            
            if (!empty($stats_items)) {
                $output .= '<div class="mt-3 pt-3 border-t" style="border-color:' . esc_attr($style['card_border']) . ';">';
                $output .= '<div class="text-xs mb-2" style="color:' . esc_attr($style['text_muted']) . ';">Server Stats</div>';
                $output .= '<div class="space-y-1.5">';
                foreach ($stats_items as $stat) {
                    $output .= '<div class="flex items-center justify-between text-xs">';
                    $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">' . esc_html($stat['label']) . ':</span>';
                    $output .= '<span class="font-medium" style="color:' . esc_attr($style['text_primary']) . ';">' . esc_html($stat['value']) . '</span>';
                    $output .= '</div>';
                }
                $output .= '</div>';
                $output .= '</div>';
            }
        }
        
        // Votes and vote button
        if ($args['show_votes'] || $args['show_vote_button']) {
            $output .= '<div class="flex flex-wrap items-center gap-2 mt-3 pt-3 border-t" style="border-color:' . esc_attr($style['card_border']) . ';">';
            if ($args['show_votes']) {
                $votes_count = $server['votes_count'] ?? 0;
                $output .= '<span style="color:' . esc_attr($style['text_muted']) . ';">Votes:</span>';
                $output .= '<span class="font-semibold" style="color:' . esc_attr($style['text_primary']) . ';">' . esc_html(number_format($votes_count)) . '</span>';
            }
            if ($args['show_vote_button'] && !empty($server['url'])) {
                $output .= '<a href="' . esc_url($server['url']) . '" target="_blank" rel="noopener noreferrer" class="ml-auto inline-flex items-center gap-1 rounded-md border px-3 py-1.5 text-xs font-semibold" style="border-color:' . esc_attr($style['accent']) . '66;background:color-mix(in srgb, ' . esc_attr($style['accent']) . ' 14%, transparent);color:' . esc_attr($style['accent']) . ';">';
                $output .= 'Vote';
                $output .= '</a>';
            }
            $output .= '</div>';
        }
        
        // Players history chart (24h)
        $show_chart = $display_options['show_chart'] ?? false;
        if ($show_chart && $this->api && !empty($server['id'])) {
            $server_id = intval($server['id']);
            $chart_label = $is_discord ? '24h Users History' : '24h Players History';
            $output .= '<div class="mt-3 pt-3 border-t" style="border-color:' . esc_attr($style['card_border']) . ';">';
            $output .= '<div class="text-xs mb-2" style="color:' . esc_attr($style['text_muted']) . ';">' . esc_html($chart_label) . '</div>';
            $output .= '<canvas id="list2play-chart-' . esc_attr($server_id) . '" class="list2play-chart" data-server-id="' . esc_attr($server_id) . '" data-chart-line="' . esc_attr($style['chart_line']) . '" data-chart-area="' . esc_attr($style['chart_area']) . '" data-chart-axis="' . esc_attr($style['chart_axis']) . '" data-chart-grid="' . esc_attr($style['chart_grid']) . '" style="max-height: 80px; width: 100%;"></canvas>';
            $output .= '</div>';
        }
        
        $output .= '</div>';
        $output .= '</div>';
        
        return $output;
    }
    
    /**
     * Render server table for desktop - using card-like structure like mobile
     */
    private function render_server_table($servers, $args = []) {
        $output = '<div class="overflow-x-auto">';
        $output .= '<table>';
        
        // Table header
        $output .= '<thead>';
        $output .= '<tr>';
        $output .= '<th>Server</th>';
        $output .= '<th>Activity</th>';
        $output .= '<th>Status</th>';
        if ($args['show_votes']) {
            $output .= '<th>Votes</th>';
        }
        $output .= '<th>Current map</th>';
        $output .= '</tr>';
        $output .= '</thead>';
        
        // Table body
        $output .= '<tbody>';
        
        foreach ($servers as $server) {
            $is_online = $server['status'] === 'online';
            $status_classes = $is_online
                ? 'border border-emerald-500/30 bg-emerald-500/15 text-emerald-300'
                : 'border border-rose-500/30 bg-rose-500/15 text-rose-300';
            
            $output .= '<tr>';
            
            // Server name column - matching mobile card structure
            $output .= '<td>';
            $output .= '<div class="flex flex-col">';
            $output .= '<a href="' . esc_url($server['url'] ?? '#') . '" class="font-semibold text-white">';
            $output .= '<span>' . esc_html($server['hostname'] ?? '') . '</span>';
            $output .= '</a>';
            
            // Server meta (address, game, country) - matching mobile badges
            $output .= '<ul class="server-meta">';
            
            // Address - matching mobile button style
            if (!empty($server['display_address'])) {
                $output .= '<li>';
                $output .= '<button type="button" data-copy="' . esc_attr($server['display_address']) . '" class="inline-flex items-center gap-1 rounded-md border border-slate-700 bg-slate-950 px-2 py-1 text-slate-200 hover:border-emerald-500 hover:text-emerald-300" title="Copy address">';
                $output .= '<svg xmlns="http://www.w3.org/2000/svg" style="height: 0.75rem; width: 0.75rem;" fill="none" viewBox="0 0 24 24" stroke="currentColor">';
                $output .= '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 7v-2a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-2M9 7h-2a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2v-2M9 7h4.5a1.5 1.5 0 0 1 1.5 1.5V13" />';
                $output .= '</svg>';
                $output .= esc_html($server['display_address']);
                $output .= '</button>';
                $output .= '</li>';
            }
            
            // Game type with icon - matching mobile badge style
            if (!empty($server['game_type'])) {
                $output .= '<li>';
                $game_type_url = !empty($server['game_type']['slug']) 
                    ? 'https://list2play.net/servers?game_type=' . urlencode($server['game_type']['id'])
                    : '#';
                $output .= '<a href="' . esc_url($game_type_url) . '" target="_blank" rel="noopener noreferrer" class="list2play-game-badge inline-flex items-center gap-2 rounded-md border border-slate-700/70 bg-slate-900/70 px-2 py-1 text-emerald-300 hover:border-emerald-500/60 hover:text-emerald-200" title="Filter by ' . esc_attr($server['game_type']['name'] ?? '') . '">';
                if (!empty($server['game_type']['icon_url'])) {
                    $icon_url = $this->get_local_game_icon_url($server['game_type']['icon_url']);
                    $output .= '<img src="' . esc_url($icon_url) . '" alt="' . esc_attr($server['game_type']['name'] ?? '') . ' icon" style="height: 1rem; width: 1rem; flex-shrink: 0; object-fit: contain;">';
                }
                $output .= '<span class="text-emerald-300" style="color: rgb(110, 231, 183); white-space: nowrap;">' . esc_html($server['game_type']['name'] ?? '') . '</span>';
                $output .= '</a>';
                $output .= '</li>';
            }
            
            // Country flag - matching mobile badge style
            if (!empty($server['country_code'])) {
                $output .= '<li>';
                $country_url = 'https://list2play.net/servers?country=' . urlencode($server['country_code']);
                $output .= '<a href="' . esc_url($country_url) . '" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 rounded-md border border-slate-700/70 bg-slate-900/70 px-2 py-1 hover:border-emerald-500/60 hover:text-emerald-200" title="Show servers from ' . esc_attr(strtoupper($server['country_code'])) . '">';
                $output .= '<span class="fi fi-' . esc_attr(strtolower($server['country_code'])) . ' fio rounded-sm"></span>';
                $output .= '<span class="text-slate-200">' . esc_html(strtoupper($server['country_code'])) . '</span>';
                $output .= '</a>';
                $output .= '</li>';
            }
            
            $output .= '</ul>';
            $output .= '</div>';
            $output .= '</td>';
            
            // Activity column (players) - matching mobile style
            $output .= '<td>';
            $output .= '<span class="inline-flex items-center gap-2 rounded-md border border-slate-700/70 bg-slate-900/70 px-2 py-1 text-slate-100">';
            if (isset($server['current_players'])) {
                $output .= esc_html($server['current_players']);
                if (!empty($server['max_players'])) {
                    $output .= '<span class="text-xs text-slate-400"> / ' . esc_html($server['max_players']) . '</span>';
                }
            } else {
                $output .= '<span class="text-slate-500">-</span>';
            }
            $output .= '</span>';
            $output .= '</td>';
            
            // Status column - matching mobile badge style
            $output .= '<td>';
            $output .= '<span class="inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ' . esc_attr($status_classes) . '">';
            $output .= esc_html(ucfirst($server['status'] ?? 'unknown'));
            $output .= '</span>';
            $output .= '</td>';
            
            // Votes column - matching mobile style
            if ($args['show_votes']) {
                $output .= '<td>';
                $votes_count = $server['votes_count'] ?? 0;
                $output .= '<span class="text-slate-200 font-semibold">' . esc_html(number_format($votes_count)) . '</span>';
                $output .= '</td>';
            }
            
            // Map column - matching mobile style
            $output .= '<td>';
            if (!empty($server['current_map'])) {
                $output .= '<span class="inline-flex items-center gap-2 rounded-md border border-slate-700/70 bg-slate-900/70 px-2 py-1 text-slate-100">';
                $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="currentColor" viewBox="0 0 24 24">';
                $output .= '<path d="m15.5 5.56-7-2a1 1 0 0 0-.63 0l-6 2A1 1 0 0 0 1 6.5v13a1 1 0 0 0 1.32.95L8 18.8l7 2a1 1 0 0 0 .63 0l6-2a1 1 0 0 0 .37-.23.998.998 0 0 0 .3-.72v-13a1 1 0 0 0-1.32-.95ZM9 5.28l6 1.72v11.72l-6-1.72Zm-2 .39v11.73l-4 1.15V6.83Zm14 11.15-4 1.15V6.15l4-1.15Z"/>';
                $output .= '</svg>';
                $output .= '<span>' . esc_html($server['current_map']) . '</span>';
                $output .= '</span>';
            } else {
                $output .= '<span class="text-slate-500">-</span>';
            }
            $output .= '</td>';
            
            $output .= '</tr>';
        }
        
        $output .= '</tbody>';
        $output .= '</table>';
        $output .= '</div>';
        
        return $output;
    }
    
    /**
     * Build a pagination URL for the current request using WordPress URL helpers.
     */
    private function get_pagination_page_url(int $page): string {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET parameters for pagination don't require nonce
        $query_params = isset($_GET) ? wp_unslash($_GET) : [];
        if (!is_array($query_params)) {
            $query_params = [];
        }
        $query_params['list2play_page'] = $page;

        $relative_url = add_query_arg($query_params);
        if (!is_string($relative_url) || $relative_url === '') {
            $relative_url = add_query_arg($query_params, '/');
        }

        return esc_url(home_url($relative_url));
    }

    /**
     * Render pagination
     */
    public function render_pagination($pagination) {
        $current = $pagination['current_page'] ?? 1;
        $last = $pagination['last_page'] ?? 1;
        $total = $pagination['total'] ?? 0;
        
        if ($last <= 1) {
            return ''; // Don't show pagination if only one page
        }
        
        $output = '<div class="list2play-pagination mt-6">';
        
        // Page info
        $output .= '<div class="list2play-pagination-info text-center text-sm text-slate-400 mb-4">';
        $output .= sprintf(
            /* translators: 1: Current page number, 2: Total pages, 3: Total servers count */
            esc_html__('Page %1$d of %2$d (%3$d servers)', 'list2play-servers'),
            $current,
            $last,
            $total
        );
        $output .= '</div>';
        
        // Pagination buttons
        $output .= '<div class="list2play-pagination-buttons flex items-center justify-center gap-2 flex-wrap">';
        
        // Previous button
        if ($current > 1) {
            $prev_url = $this->get_pagination_page_url($current - 1);
            $output .= '<a href="' . $prev_url . '" class="list2play-pagination-btn list2play-pagination-prev inline-flex items-center gap-1 px-4 py-2 text-sm font-medium text-slate-300 bg-slate-800/70 border border-slate-700 rounded-lg hover:bg-slate-700 hover:text-white transition-colors">';
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /></svg>';
            $output .= esc_html__('Previous', 'list2play-servers');
            $output .= '</a>';
        } else {
            $output .= '<span class="list2play-pagination-btn list2play-pagination-prev inline-flex items-center gap-1 px-4 py-2 text-sm font-medium text-slate-500 bg-slate-800/30 border border-slate-700/50 rounded-lg cursor-not-allowed opacity-50">';
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /></svg>';
            $output .= esc_html__('Previous', 'list2play-servers');
            $output .= '</span>';
        }
        
        // Page numbers
        $output .= '<div class="list2play-pagination-numbers flex items-center gap-1">';
        
        // Show first page if not near start
        if ($current > 3) {
            $first_url = $this->get_pagination_page_url(1);
            $output .= '<a href="' . $first_url . '" class="list2play-pagination-number inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm font-medium text-slate-300 bg-slate-800/70 border border-slate-700 rounded-lg hover:bg-slate-700 hover:text-white transition-colors">1</a>';
            if ($current > 4) {
                $output .= '<span class="inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm text-slate-500">...</span>';
            }
        }
        
        // Show pages around current
        $start = max(1, $current - 2);
        $end = min($last, $current + 2);
        
        for ($i = $start; $i <= $end; $i++) {
            if ($i == $current) {
                $output .= '<span class="list2play-pagination-number list2play-pagination-current inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm font-medium text-white bg-emerald-600 border border-emerald-500 rounded-lg">' . $i . '</span>';
            } else {
                $page_url = $this->get_pagination_page_url($i);
                $output .= '<a href="' . $page_url . '" class="list2play-pagination-number inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm font-medium text-slate-300 bg-slate-800/70 border border-slate-700 rounded-lg hover:bg-slate-700 hover:text-white transition-colors">' . $i . '</a>';
            }
        }
        
        // Show last page if not near end
        if ($current < $last - 2) {
            if ($current < $last - 3) {
                $output .= '<span class="inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm text-slate-500">...</span>';
            }
            $last_url = $this->get_pagination_page_url($last);
            $output .= '<a href="' . $last_url . '" class="list2play-pagination-number inline-flex items-center justify-center min-w-[2.5rem] h-10 text-sm font-medium text-slate-300 bg-slate-800/70 border border-slate-700 rounded-lg hover:bg-slate-700 hover:text-white transition-colors">' . $last . '</a>';
        }
        
        $output .= '</div>'; // .list2play-pagination-numbers
        
        // Next button
        if ($current < $last) {
            $next_url = $this->get_pagination_page_url($current + 1);
            $output .= '<a href="' . $next_url . '" class="list2play-pagination-btn list2play-pagination-next inline-flex items-center gap-1 px-4 py-2 text-sm font-medium text-slate-300 bg-slate-800/70 border border-slate-700 rounded-lg hover:bg-slate-700 hover:text-white transition-colors">';
            $output .= esc_html__('Next', 'list2play-servers');
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>';
            $output .= '</a>';
        } else {
            $output .= '<span class="list2play-pagination-btn list2play-pagination-next inline-flex items-center gap-1 px-4 py-2 text-sm font-medium text-slate-500 bg-slate-800/30 border border-slate-700/50 rounded-lg cursor-not-allowed opacity-50">';
            $output .= esc_html__('Next', 'list2play-servers');
            $output .= '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>';
            $output .= '</span>';
        }
        
        $output .= '</div>'; // .list2play-pagination-buttons
        $output .= '</div>'; // .list2play-pagination
        
        return $output;
    }
}
