<?php
/**
 * Example 10 — Server-Side Request Handler
 *
 * Shows how to handle the AJAX requests sent by the DataSet table
 * on the server side, using ServerSideRequest and ServerSideResponse.
 *
 * This would typically live in your API controller or route handler.
 */

declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Italix\DataSets\ServerSideRequest;
use Italix\DataSets\ServerSideResponse;

// ============================================================================
// Parse the incoming request
// ============================================================================

// From PHP superglobals (auto-detects GET vs POST):
$request = ServerSideRequest::from_globals();

// Or from a framework's request object:
// $request = ServerSideRequest::from_array($frameworkRequest->all());

// ============================================================================
// Build your database query using the parsed parameters
// ============================================================================

// --- Pagination ---
$page     = $request->page();          // int, 1-based
$per_page = $request->per_page();      // int, default 25
$offset   = $request->offset();        // int, calculated

// --- Sorting ---

// Simple single-column sort:
$sort_col = $request->sort_column('created_at');  // string or null
$sort_dir = $request->sort_direction('desc');      // 'asc' or 'desc'

// Multi-column sort (when user shift-clicks multiple headers):
$sorts = $request->sorts();
// Returns: [
//   ['column' => 'status', 'direction' => 'asc'],
//   ['column' => 'created_at', 'direction' => 'desc'],
// ]

// --- Global search ---
$search_query   = $request->search();          // string or null
$search_columns = $request->search_columns();  // e.g. ['name', 'email']

// --- Column filters (from header filters) ---
$filters = $request->filters();  // e.g. ['role' => 'admin', 'status' => 'active']
$role_filter = $request->filter('role');  // 'admin' or null

// --- Raw access ---
$tenant = $request->get('tenant');  // any custom param from ajax_params()


// ============================================================================
// Example: PDO query builder
// ============================================================================

$where_clauses = [];
$bind_params = [];

// Global search: OR across searchable columns
if ($search_query !== null && !empty($search_columns)) {
    $search_or = [];
    foreach ($search_columns as $i => $col) {
        // IMPORTANT: validate $col against allowed column names!
        $allowed = ['name', 'email', 'role'];
        if (in_array($col, $allowed, true)) {
            $param = ':search_' . $i;
            $search_or[] = "{$col} LIKE {$param}";
            $bind_params[$param] = '%' . $search_query . '%';
        }
    }
    if (!empty($search_or)) {
        $where_clauses[] = '(' . implode(' OR ', $search_or) . ')';
    }
}

// Column filters: AND
foreach ($filters as $col => $value) {
    $allowed = ['role', 'status'];
    if (in_array($col, $allowed, true)) {
        $param = ':filter_' . $col;
        $where_clauses[] = "{$col} = {$param}";
        $bind_params[$param] = $value;
    }
}

$where_sql = !empty($where_clauses) ? 'WHERE ' . implode(' AND ', $where_clauses) : '';

// Sorting (validate column names!)
$order_parts = [];
$allowed_sort = ['name', 'email', 'role', 'created_at', 'status'];

if (!empty($sorts)) {
    // Multi-column sort
    foreach ($sorts as $sort) {
        if (in_array($sort['column'], $allowed_sort, true)) {
            $dir = $sort['direction'] === 'desc' ? 'DESC' : 'ASC';
            $order_parts[] = "{$sort['column']} {$dir}";
        }
    }
} elseif ($sort_col !== null && in_array($sort_col, $allowed_sort, true)) {
    // Single-column sort fallback
    $dir = $sort_dir === 'desc' ? 'DESC' : 'ASC';
    $order_parts[] = "{$sort_col} {$dir}";
}

$order_sql = !empty($order_parts) ? 'ORDER BY ' . implode(', ', $order_parts) : '';

// Count total
$count_sql = "SELECT COUNT(*) FROM users {$where_sql}";
$count_stmt = $pdo->prepare($count_sql);
$count_stmt->execute($bind_params);
$total = (int)$count_stmt->fetchColumn();

// Fetch the page
$data_sql = "SELECT id, name, email, role, created_at FROM users {$where_sql} {$order_sql} LIMIT :limit OFFSET :offset";
$data_stmt = $pdo->prepare($data_sql);
foreach ($bind_params as $k => $v) {
    $data_stmt->bindValue($k, $v);
}
$data_stmt->bindValue(':limit', $per_page, PDO::PARAM_INT);
$data_stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$data_stmt->execute();
$rows = $data_stmt->fetchAll(PDO::FETCH_ASSOC);


// ============================================================================
// Build and send the response
// ============================================================================

// Option A: Build manually
$response = new ServerSideResponse($rows, $total, $page, $per_page);

// Option B: Build from the request (auto-extracts page and per_page)
$response = ServerSideResponse::from_request($rows, $total, $request);

// Inspect before sending:
// $response->to_array() returns:
// [
//     'data'      => [...rows...],
//     'total'     => 150,
//     'page'      => 3,
//     'per_page'  => 25,
//     'last_page' => 6,
// ]

// Send as JSON HTTP response (sets Content-Type header and exits):
$response->send();