<?php
/**
 * TrackSharp Events Page
 * 
 * Handles the events log page.
 *
 * @package TrackSharp
 */

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

class TrackSharp_Events_Page
{
    private const EXPORT_NONCE_ACTION = 'tracksharp_events_export';
    private const EXPORT_NONCE_PARAM = 'ws_nonce';

    /** @var TrackSharp_Events_Log */
    private $events_log;

    /**
     * Constructor.
     *
     * @param TrackSharp_Events_Log $events_log Events logger.
     */
    public function __construct(TrackSharp_Events_Log $events_log)
    {
        $this->events_log = $events_log;
    }

    /**
     * Render the events page.
     *
     * @return void
     */
    public function render()
    {
        if (!current_user_can('manage_options')) {
            return;
        }

        global $wpdb;
        $table = esc_sql($this->events_log->table_name());

        // Get filters
        $txid = isset($_GET['txid']) ? sanitize_text_field(wp_unslash($_GET['txid'])) : '';
        $event = isset($_GET['event']) ? sanitize_text_field(wp_unslash($_GET['event'])) : '';
        $channel = isset($_GET['channel']) ? sanitize_text_field(wp_unslash($_GET['channel'])) : '';
        $source = isset($_GET['source']) ? sanitize_text_field(wp_unslash($_GET['source'])) : '';
        $ok = isset($_GET['ok']) ? sanitize_text_field(wp_unslash($_GET['ok'])) : '';

        // Handle CSV export
        if (isset($_GET['ws_export'])) {
            $this->handle_export($wpdb, $table, $txid, $event, $channel, $source, $ok);
            return;
        }

        // Build query
        $where = ["LOWER(event_name) NOT IN ('view_item','viewcontent','pageview')"];
        $args = [];

        if ($txid !== '') {
            $where[] = 'txid LIKE %s';
            $args[] = '%' . $wpdb->esc_like($txid) . '%';
        }
        if ($event !== '') {
            $where[] = 'event_name = %s';
            $args[] = $event;
        }
        if ($channel !== '') {
            $where[] = 'channel = %s';
            $args[] = $channel;
        }
        if ($source !== '') {
            $where[] = 'source = %s';
            $args[] = $source;
        }
        if ($ok !== '' && ($ok === '0' || $ok === '1')) {
            $where[] = 'ok = %d';
            $args[] = (int) $ok;
        }

        $whereSql = implode(' AND ', $where);

        // Pagination
        $per_page = 100;
        $paged = max(1, isset($_GET['paged']) ? (int) $_GET['paged'] : 1);
        $offset = ($paged - 1) * $per_page;

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared -- Table name is escaped, WHERE conditions use placeholders
        $sql_count = "SELECT COUNT(*) FROM {$table} WHERE {$whereSql}";
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query uses $wpdb->prepare() with placeholders
        $total = (int) $wpdb->get_var($wpdb->prepare($sql_count, ...$args));

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared -- Table name is escaped, WHERE conditions use placeholders
        $sql = "SELECT id, ts, channel, source, event_name, event_id, txid, ok, http_status, consent, ua
                FROM {$table}
                WHERE {$whereSql}
                ORDER BY id DESC
                LIMIT %d OFFSET %d";
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query uses $wpdb->prepare() with placeholders
        $rows = $wpdb->get_results($wpdb->prepare($sql, ...array_merge($args, [$per_page, $offset])), ARRAY_A);

        $total_pages = max(1, (int) ceil($total / $per_page));
        $reset_url = admin_url('admin.php?page=tracksharp-events');
        $base_args = $this->build_query_args($txid, $event, $channel, $source, $ok);
        $export_url = add_query_arg(
            array_merge(
                $base_args,
                [
                    'ws_export' => 1,
                    self::EXPORT_NONCE_PARAM => wp_create_nonce(self::EXPORT_NONCE_ACTION),
                ]
            ),
            $reset_url
        );

        $this->render_page($txid, $event, $channel, $source, $ok, $rows, $total, $paged, $total_pages, $per_page, $reset_url, $export_url);
    }

    /**
     * Build a whitelist of query vars for pagination/export URLs.
     *
     * @return array<string, string>
     */
    private function build_query_args($txid, $event, $channel, $source, $ok): array
    {
        $args = [];

        if ($txid !== '') {
            $args['txid'] = $txid;
        }
        if ($event !== '') {
            $args['event'] = $event;
        }
        if ($channel !== '') {
            $args['channel'] = $channel;
        }
        if ($source !== '') {
            $args['source'] = $source;
        }
        if ($ok !== '' && ($ok === '0' || $ok === '1')) {
            $args['ok'] = $ok;
        }

        return $args;
    }

    /**
     * Handle CSV export.
     */
    private function handle_export($wpdb, $table_raw, $txid, $event, $channel, $source, $ok)
    {
        $nonce = isset($_GET[self::EXPORT_NONCE_PARAM]) ? sanitize_text_field(wp_unslash($_GET[self::EXPORT_NONCE_PARAM])) : '';
        if (!$nonce || !wp_verify_nonce($nonce, self::EXPORT_NONCE_ACTION)) {
            wp_die(esc_html__('Invalid export link. Please refresh and try again.', 'tracksharp'), 403);
        }

        $table = esc_sql($table_raw);
        $where = ["LOWER(event_name) NOT IN ('view_item','viewcontent','pageview')"];
        $args = [];

        if ($txid !== '') {
            $where[] = 'txid LIKE %s';
            $args[] = '%' . $wpdb->esc_like($txid) . '%';
        }
        if ($event !== '') {
            $where[] = 'event_name = %s';
            $args[] = $event;
        }
        if ($channel !== '') {
            $where[] = 'channel = %s';
            $args[] = $channel;
        }
        if ($source !== '') {
            $where[] = 'source = %s';
            $args[] = $source;
        }
        if ($ok !== '' && ($ok === '0' || $ok === '1')) {
            $where[] = 'ok = %d';
            $args[] = (int) $ok;
        }

        $whereSql = implode(' AND ', $where);

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared -- Table name is escaped, WHERE conditions use placeholders
        $sql = "SELECT id, ts, channel, source, event_name, event_id, txid, ok, http_status, consent, ua
                FROM {$table}
                WHERE {$whereSql}
                ORDER BY id DESC
                LIMIT 10000";
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query uses $wpdb->prepare() with placeholders
        $rows = $wpdb->get_results($wpdb->prepare($sql, ...$args), ARRAY_A);

        nocache_headers();
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=ws_events.csv');

        $out = fopen('php://output', 'w');
        fputcsv($out, $rows ? array_keys($rows[0]) : ['id', 'ts', 'channel', 'source', 'event_name', 'event_id', 'txid', 'ok', 'http_status', 'consent', 'ua']);

        if ($rows) {
            foreach ($rows as $r) {
                fputcsv($out, $r);
            }
        }

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- fclose required for php://output stream
        fclose($out);
        exit;
    }

    /**
     * Render the page HTML.
     */
    private function render_page($txid, $event, $channel, $source, $ok, $rows, $total, $paged, $total_pages, $per_page, $reset_url, $export_url)
    {
        $base_args = $this->build_query_args($txid, $event, $channel, $source, $ok);
        ?>
        <div class="wrap tracksharp-admin tracksharp-admin--wide">
            <div class="ws-card">
                <div class="ws-card-header">
                    <div>
                        <h1>TrackSharp Events</h1>
                        <p class="ws-desc">Raw log for debugging and verification.</p>
                    </div>
                    <a class="button" href="<?php echo esc_url(admin_url('admin.php?page=tracksharp-audit')); ?>">Dashboard</a>
                </div>
            </div>

            <div class="ws-card">
                <form method="get" class="ws-filter-bar">
                    <input type="hidden" name="page" value="tracksharp-events" />
                    <div class="ws-filter-field">
                        <label for="ws-filter-txid">Transaction ID</label>
                        <input type="text" id="ws-filter-txid" name="txid" placeholder="Order number"
                            value="<?php echo esc_attr($txid); ?>" />
                    </div>
                    <div class="ws-filter-field">
                        <label for="ws-filter-event">Event name</label>
                        <input type="text" id="ws-filter-event" name="event" placeholder="purchase"
                            value="<?php echo esc_attr($event); ?>" />
                    </div>
                    <div class="ws-filter-field">
                        <label for="ws-filter-channel">Channel</label>
                        <select id="ws-filter-channel" name="channel">
                            <option value="">Channel</option>
                            <option value="ga4" <?php selected($channel, 'ga4'); ?>>GA4</option>
                            <option value="meta" <?php selected($channel, 'meta'); ?>>Meta</option>
                        </select>
                    </div>
                    <div class="ws-filter-field">
                        <label for="ws-filter-source">Source</label>
                        <select id="ws-filter-source" name="source">
                            <option value="">Source</option>
                            <option value="server" <?php selected($source, 'server'); ?>>Server</option>
                            <option value="browser" <?php selected($source, 'browser'); ?>>Browser</option>
                        </select>
                    </div>
                    <div class="ws-filter-field">
                        <label for="ws-filter-ok">Status</label>
                        <select id="ws-filter-ok" name="ok">
                            <option value="">Status</option>
                            <option value="1" <?php selected($ok, '1'); ?>>OK</option>
                            <option value="0" <?php selected($ok, '0'); ?>>Error</option>
                        </select>
                    </div>
                    <div class="ws-filter-actions">
                        <button class="button button-primary">Filter</button>
                        <a class="button" href="<?php echo esc_url($reset_url); ?>">Reset</a>
                        <a class="button" href="<?php echo esc_url($export_url); ?>">Export (.csv)</a>
                    </div>
                </form>
            </div>

            <div class="ws-card ws-card-table">
                <div class="ws-card-table__meta">
                    <strong><?php echo esc_html(number_format_i18n($total)); ?></strong>
                    <span>Page <?php echo (int) $paged; ?> / <?php echo (int) $total_pages; ?></span>
                </div>
                <table>
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Time</th>
                            <th>Channel</th>
                            <th>Source</th>
                            <th>Event</th>
                            <th>Event ID</th>
                            <th>Transaction ID</th>
                            <th>Status</th>
                            <th>HTTP</th>
                            <th>Consent</th>
                            <th>User agent</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php if (!$rows): ?>
                            <tr>
                                <td colspan="11">No rows found.</td>
                            </tr>
                        <?php else: ?>
                            <?php foreach ($rows as $r): ?>
                                <tr>
                                    <td><?php echo (int) $r['id']; ?></td>
                                    <td><?php echo esc_html($r['ts']); ?></td>
                                    <td><?php echo esc_html($r['channel']); ?></td>
                                    <td><?php echo esc_html($r['source']); ?></td>
                                    <td><?php echo esc_html($r['event_name']); ?></td>
                                    <td class="ws-clip"><?php echo esc_html($r['event_id']); ?></td>
                                    <td class="ws-clip"><?php echo esc_html($r['txid']); ?></td>
                                    <td>
                                        <span class="ws-status <?php echo $r['ok'] ? 'ws-status-ok' : 'ws-status-bad'; ?>">
                                            <?php echo $r['ok'] ? 'OK' : 'Error'; ?>
                                        </span>
                                    </td>
                                    <td><?php echo esc_html($r['http_status']); ?></td>
                                    <td><?php echo esc_html($r['consent']); ?></td>
                                    <td class="ws-clip" title="<?php echo esc_attr($r['ua']); ?>"><?php echo esc_html(TrackSharp_Events_Log::parse_browser($r['ua'])); ?></td>
                                </tr>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div>

            <div class="ws-card">
                <div class="ws-pagination">
                    <div>
                        <strong><?php echo esc_html(number_format_i18n($per_page)); ?></strong> rows per page
                    </div>
                    <?php if ($total_pages > 1): ?>
                        <div class="ws-page-list">
                            <?php for ($i = 1; $i <= $total_pages; $i++): ?>
                                <a class="ws-page-btn <?php echo $i === $paged ? 'is-active' : ''; ?>"
                                    href="<?php echo esc_url(add_query_arg(array_merge($base_args, ['paged' => $i]), $reset_url)); ?>">
                                    <?php echo (int) $i; ?>
                                </a>
                            <?php endfor; ?>
                        </div>
                    <?php endif; ?>
                </div>
            </div>
        </div>
        <?php
    }
}
