/home/edulekha/crm.edulekha.com/modules/appointly/views/tables/appointments_stats.php
<?php defined('BASEPATH') or exit('No direct script access allowed');

// Only include actual database columns here
$aColumns = [
    'staffid',
    'firstname',
    'lastname'
];

// Define which columns can be sorted in the database
$notsortable = []; // We'll override this to control sorting

$sIndexColumn = 'staffid';
$sTable       = db_prefix() . 'staff';

// Get date filters from post
$date_from = $this->ci->input->post('date_from');
$date_to = $this->ci->input->post('date_to');

// Default date range if not provided
if (empty($date_from)) {
    $date_from = date('Y-m-01'); // First day of current month
}
if (empty($date_to)) {
    $date_to = date('Y-m-t'); // Last day of current month
}

// Only active staff members
$where = [];
array_push($where, 'AND active = 1');

// Override ordering to ensure we only sort by valid database columns
if (isset($_POST['order']) && isset($_POST['order'][0]['column'])) {
    $order_column_index = $_POST['order'][0]['column'];
    // If trying to sort by a non-database column, force sorting by staffid
    if ($order_column_index > 0) { // First column (staff name) is valid
        $_POST['order'][0]['column'] = 0; // Sort by staff id as default
    }
}

// Initialize the basic DataTable with only the actual database columns
$result = data_tables_init($aColumns, $sIndexColumn, $sTable, [], $where);

$output  = $result['output'];
$rResult = $result['rResult'];

$output['aaData'] = [];

// Load the reports model to get performance data
$this->ci->load->model('appointly/reports_model');
$staff_performance = $this->ci->reports_model->get_staff_performance($date_from, $date_to);

// Track if we found any staff with appointments
$hasAppointments = false;

// Process data
foreach ($rResult as $aRow) {
    $staffId = $aRow['staffid'];

    // Find this staff's performance data
    $performanceData = null;
    foreach ($staff_performance as $performance) {
        if ($performance['staffid'] == $staffId) {
            $performanceData = $performance;
            break;
        }
    }

    // Skip staff with no appointments
    if (!$performanceData || !isset($performanceData['total']) || $performanceData['total'] == 0) {
        continue;
    }

    // We found at least one staff with appointments
    $hasAppointments = true;

    $row = [];

    // Staff Member with link to profile
    $staffName = trim($aRow['firstname'] . ' ' . $aRow['lastname']);
    $row[] = '<a href="' . admin_url('staff/profile/' . $staffId) . '">' . $staffName . '</a>';

    // Total Appointments
    $row[] = $performanceData['total'] ?? 0;

    // Completed Appointments
    $row[] = $performanceData['completed'] ?? 0;

    // Cancelled Appointments
    $row[] = $performanceData['cancelled'] ?? 0;

    // Completion Rate
    $completionRate = $performanceData['completion_rate'] ?? 0;
    $row[] = $completionRate . '%';

    //  data for custom sorting (these values won't be displayed)
    $row['DT_RowData'] = [
        'total' => $performanceData['total'] ?? 0,
        'completed' => $performanceData['completed'] ?? 0,
        'cancelled' => $performanceData['cancelled'] ?? 0,
        'completion_rate' => $completionRate
    ];

    //  row to output
    $output['aaData'][] = $row;
}

// If no staff with appointments were found, add a row indicating no data
if (!$hasAppointments) {
    $row = [
        '<span class="no-data-message">' . _l('appointly_no_data_found') . '</span>',
        '0',
        '0',
        '0',
        '0%'
    ];
    $output['aaData'][] = $row;
}

// Apply custom sorting based on order parameter if needed
if (isset($_POST['order'])) {
    $order = $_POST['order'][0];
    $columnIndex = $order['column'];
    $direction = $order['dir'];

    // If sorting by a calculated column (1=total, 2=completed, 3=cancelled, 4=rate)
    if ($columnIndex > 0) {
        // Map column index to field name
        $sortFields = ['total', 'completed', 'cancelled', 'completion_rate'];
        // Adjust index for the sortFields array (column 1->0, 2->1, etc.)
        $sortFieldIndex = $columnIndex - 1;

        if (isset($sortFields[$sortFieldIndex])) {
            $field = $sortFields[$sortFieldIndex];

            usort($output['aaData'], function ($a, $b) use ($field, $direction) {
                // Get values to compare (using DT_RowData for proper numeric comparison)
                $aVal = isset($a['DT_RowData'][$field]) ? $a['DT_RowData'][$field] : 0;
                $bVal = isset($b['DT_RowData'][$field]) ? $b['DT_RowData'][$field] : 0;

                // Convert to integers or floats for proper comparison
                if (is_numeric($aVal)) $aVal = floatval($aVal);
                if (is_numeric($bVal)) $bVal = floatval($bVal);

                // Compare values based on direction
                if ($direction === 'asc') {
                    return $aVal <=> $bVal;
                } else {
                    return $bVal <=> $aVal;
                }
            });
        }
    }
}

echo json_encode($output);
die(); // Required for AJAX datatable response