<?php
/**
 * Example Module - Items AJAX Handler
 *
 * Complete CRUD operations with DataTables SSP.
 */

// Dispatcher
if (isset($_POST['acc']) && function_exists($_POST['acc'])) {
    $_POST['acc']();
}

/**
 * Gets items list for DataTables.
 */
function getItems(): void
{
    $es_index = getEsIndex();

    // Get DataTables parameters
    $searchTerm = $_POST['search']['value'] ?? '';
    $start = (int)($_POST['start'] ?? 0);
    $length = (int)($_POST['length'] ?? 10);
    $draw = (int)($_POST['draw'] ?? 1);

    // Custom filters
    $filterStatus = getPostString('filterStatus');
    $filterCategory = getPostString('filterCategory');

    // Build search conditions
    $search = ['(slm.type:item)'];

    if (!empty($filterStatus)) {
        $search[] = "(status.keyword:" . escapeEsValue($filterStatus) . ")";
    }

    if (!empty($filterCategory)) {
        $search[] = "(category.keyword:" . escapeEsValue($filterCategory) . ")";
    }

    // Searchable fields
    $fields = ['name.keyword', 'description', 'category.keyword'];

    // SSP parameters
    $params = [
        'from' => $start,
        'size' => $length,
        'sort' => 'slm.timestamp',
        'order' => 'desc'
    ];

    // Handle DataTables sorting
    if (isset($_POST['order'][0])) {
        $columns = ['name.keyword', 'description', 'category.keyword', 'status.keyword', 'slm.timestamp'];
        $orderColumn = (int)$_POST['order'][0]['column'];
        $orderDir = $_POST['order'][0]['dir'] === 'asc' ? 'asc' : 'desc';

        if (isset($columns[$orderColumn])) {
            $params['sort'] = $columns[$orderColumn];
            $params['order'] = $orderDir;
        }
    }

    try {
        $ssp = new SSP($searchTerm, $search, $fields, $params);
        $result = $ssp->setEsIndex($es_index)->setReturn(true)->run();

        $response = [
            'draw' => $draw,
            'recordsTotal' => $result['recordsTotal'],
            'recordsFiltered' => $result['recordsFiltered'],
            'data' => $result['data']
        ];

        exit(json_encode($response));

    } catch (Exception $e) {
        exit(json_encode([
            'draw' => $draw,
            'recordsTotal' => 0,
            'recordsFiltered' => 0,
            'data' => [],
            'error' => $e->getMessage()
        ]));
    }
}

/**
 * Gets a single item by ID.
 */
function getItem(): void
{
    $response = _response(true);
    $log_type = 'error';
    $log_data = [];

    try {
        $id = getPostString('id');

        if (empty($id)) {
            throw new InvalidArgumentException('Item ID is required');
        }

        $item = getObjectById($id);

        if (!$item) {
            throw new RuntimeException('Item not found');
        }

        $response = _response(false, '', ['item' => array_merge(['id' => $id], $item)]);
        $log_type = 'success';

    } catch (Exception $e) {
        $response['message'] = $e->getMessage();
    } finally {
        $log_data['return'] = $response;
        addToLog($log_type, 'example', __FUNCTION__, $log_data);
    }

    exit(json_encode($response));
}

/**
 * Creates a new item.
 */
function createItem(): void
{
    $response = _response(true);
    $log_type = 'error';
    $log_data = [];

    try {
        // Validate required fields
        validateRequiredFields(['name', 'category']);

        // Get and sanitize inputs
        $name = getPostString('name');
        $category = getPostString('category');
        $description = getPostString('description');
        $price = (float)getPostValue('price', 0);
        $status = getPostString('status') ?: 'active';
        $tags = getPostString('tags');

        // Validate category
        $validCategories = ['general', 'special', 'premium'];
        if (!in_array($category, $validCategories)) {
            throw new InvalidArgumentException('Invalid category');
        }

        // Validate status
        $validStatuses = ['active', 'inactive'];
        if (!in_array($status, $validStatuses)) {
            throw new InvalidArgumentException('Invalid status');
        }

        // Prepare document
        $tmp = [
            'name' => $name,
            'category' => $category,
            'description' => $description,
            'price' => $price,
            'status' => $status,
            'tags' => array_filter(array_map('trim', explode(',', $tags))),
            'slm' => [
                'type' => 'item',
                'timestamp' => getTimestamp(),
                'created_by' => _SLM::$session['user']['id'] ?? null
            ]
        ];

        // Save to Elasticsearch
        $result = setNewObject($tmp);

        // Validate result
        if (!_validateEsCreateResult($result)) {
            throw new RuntimeException('Failed to create item');
        }

        $response = _response(false, 'Item created successfully', [
            'id' => $result['_id'],
            'closeModal' => true,
            'reloadTable' => true
        ]);
        $log_type = 'success';

    } catch (Exception $e) {
        $response['message'] = $e->getMessage();
    } finally {
        $log_data['return'] = $response;
        addToLog($log_type, 'example', __FUNCTION__, $log_data);
    }

    exit(json_encode($response));
}

/**
 * Updates an existing item.
 */
function updateItem(): void
{
    $response = _response(true);
    $log_type = 'error';
    $log_data = [];

    try {
        // Validate required fields
        validateRequiredFields(['id', 'name', 'category']);

        $id = getPostString('id');
        $name = getPostString('name');
        $category = getPostString('category');
        $description = getPostString('description');
        $price = (float)getPostValue('price', 0);
        $status = getPostString('status') ?: 'active';
        $tags = getPostString('tags');

        // Check if item exists
        $existing = getObjectById($id);
        if (!$existing) {
            throw new RuntimeException('Item not found');
        }

        // Validate category
        $validCategories = ['general', 'special', 'premium'];
        if (!in_array($category, $validCategories)) {
            throw new InvalidArgumentException('Invalid category');
        }

        // Prepare update data
        $tmp = [
            'name' => $name,
            'category' => $category,
            'description' => $description,
            'price' => $price,
            'status' => $status,
            'tags' => array_filter(array_map('trim', explode(',', $tags))),
            'slm' => [
                'type' => 'item',
                'timestamp' => getTimestamp(),
                'updated_by' => _SLM::$session['user']['id'] ?? null
            ]
        ];

        // Update in Elasticsearch
        $result = updateObjectByID($id, $tmp);

        // Validate result
        if (!_validateEsUpdateResult($result)) {
            throw new RuntimeException('Failed to update item');
        }

        $response = _response(false, 'Item updated successfully', [
            'closeModal' => true,
            'reloadTable' => true
        ]);
        $log_type = 'success';

    } catch (Exception $e) {
        $response['message'] = $e->getMessage();
    } finally {
        $log_data['return'] = $response;
        addToLog($log_type, 'example', __FUNCTION__, $log_data);
    }

    exit(json_encode($response));
}

/**
 * Deletes (soft-delete) an item.
 */
function deleteItem(): void
{
    $response = _response(true);
    $log_type = 'error';
    $log_data = [];

    try {
        $id = getPostString('id');

        if (empty($id)) {
            throw new InvalidArgumentException('Item ID is required');
        }

        // Check if item exists
        $existing = getObjectById($id);
        if (!$existing) {
            throw new RuntimeException('Item not found');
        }

        // Soft delete - set status to inactive
        $tmp = [
            'status' => 'inactive',
            'slm' => [
                'type' => 'item',
                'timestamp' => getTimestamp(),
                'deleted_by' => _SLM::$session['user']['id'] ?? null
            ]
        ];

        $result = updateObjectByID($id, $tmp);

        if (!_validateEsUpdateResult($result)) {
            throw new RuntimeException('Failed to delete item');
        }

        $response = _response(false, 'Item deleted successfully', [
            'reloadTable' => true
        ]);
        $log_type = 'success';

    } catch (Exception $e) {
        $response['message'] = $e->getMessage();
    } finally {
        $log_data['return'] = $response;
        addToLog($log_type, 'example', __FUNCTION__, $log_data);
    }

    exit(json_encode($response));
}

// ============================================================================
// HELPER FUNCTIONS
// ============================================================================

/**
 * Validates Elasticsearch create result.
 *
 * @param array $result ES response
 * @return bool True if successful
 */
function _validateEsCreateResult(array $result): bool
{
    if (isset($result['error'])) {
        return false;
    }

    return isset($result['result']) && $result['result'] === 'created';
}

/**
 * Validates Elasticsearch update result.
 *
 * @param array $result ES response
 * @return bool True if successful
 */
function _validateEsUpdateResult(array $result): bool
{
    if (isset($result['error'])) {
        return false;
    }

    return isset($result['result']) && in_array($result['result'], ['updated', 'noop']);
}
