<?php
error_reporting(0);
ini_set('display_errors', '0');
require_once __DIR__ . '/../config/auth.php';

if (!function_exists('is_admin')) {
    function is_admin(array $user): bool { return (int)$user['user_type_id'] === 1; }
}
if (!function_exists('allowed_clients')) {
    function allowed_clients(array $user): ?array {
        if (is_admin($user)) return null;
        $ids = array_values(array_filter(array_map('intval', explode(',', $user['clients_multi'] ?? ''))));
        return $ids ?: [-1];
    }
}
if (!function_exists('client_where')) {
    function client_where(array $user, string $col = 'clients_id'): array {
        $ids = allowed_clients($user);
        if ($ids === null) return ['1=1', []];
        $ph = implode(',', array_fill(0, count($ids), '?'));
        return ["$col IN ($ph)", $ids];
    }
}

$user = require_auth();

$db     = db();
$action = $_POST['action'] ?? $_GET['action'] ?? 'list';
$id     = (int)($_POST['id'] ?? $_GET['id'] ?? 0);

try {

switch ($action) {

    case 'list':
        $status = $_GET['status'] ?? '';
        $where  = '1=1';
        $params = [];
        if ($status) { $where .= ' AND b.status = ?'; $params[] = $status; }
        // Non-admins: restrict to their assigned clients
        [$cw, $cp] = client_where($user, 'b.clients_id');
        if ($cw !== '1=1') {
            $where  .= " AND ($cw)";
            $params  = array_merge($params, $cp);
        }
        $stmt = $db->prepare(
            "SELECT b.*, c.clients_name, u.safesure_users_name as assessor_name, u.name as assessor_full_name
             FROM bookings b
             LEFT JOIN clients c ON c.record_id = b.clients_id
             LEFT JOIN safesure_users u ON u.record_id = b.safesure_users_id
             WHERE $where
             ORDER BY b.record_id DESC"
        );
        $stmt->execute($params);
        $rows = $stmt->fetchAll();
        // Decode JSON-stored employee/assessment lists
        foreach ($rows as &$row) {
            $row['client_employees_arr'] = array_filter(array_map('intval', explode(',', $row['client_employees'] ?? '')));
            $row['assessments_arr']      = array_filter(array_map('intval', explode(',', $row['assessments'] ?? '')));
            $row['tests_arr']            = array_filter(array_map('intval', explode(',', $row['tests'] ?? '')));
        }
        json_success(['bookings' => $rows]);
        break;

    case 'get':
        if (!$id) json_error('ID required');
        $stmt = $db->prepare(
            'SELECT b.*, c.clients_name, u.safesure_users_name as assessor_name, u.name as assessor_full_name
             FROM bookings b
             LEFT JOIN clients c ON c.record_id = b.clients_id
             LEFT JOIN safesure_users u ON u.record_id = b.safesure_users_id
             WHERE b.record_id=?'
        );
        $stmt->execute([$id]);
        $booking = $stmt->fetch();
        if (!$booking) json_error('Not found', 404);

        // Parse all four positional CSV strings the same way:
        // split by comma, trim each part, keep the raw strings (not intval)
        // so ,4466 ,30644, stays as ['','4466','30644',''] — JS handles alignment
        $booking['emp_parts']  = explode(',', $booking['client_employees'] ?? '');
        $booking['ass_parts']  = explode(',', $booking['assessments']      ?? '');
        $booking['test_parts'] = explode(',', $booking['tests']            ?? '');
        $booking['site_parts'] = explode(',', $booking['client_sites']     ?? '');

        // Collect unique non-zero employee IDs for the lookup
        $emp_ids = array_values(array_unique(array_filter(array_map(
            fn($v) => (int)trim($v),
            $booking['emp_parts']
        ))));

        // Return employees keyed by record_id for fast JS lookup
        $booking['employees_map'] = (object)[];
        if ($emp_ids) {
            $ph   = implode(',', array_fill(0, count($emp_ids), '?'));
            $stmt = $db->prepare("SELECT record_id, client_employees_name, surname, i_doc_passport, occupation FROM client_employees WHERE record_id IN ($ph)");
            $stmt->execute($emp_ids);
            $map = [];
            while ($row = $stmt->fetch()) {
                $map[(string)$row['record_id']] = $row;
            }
            $booking['employees_map'] = $map;
        }

        // Collect unique assessment IDs for lookup
        $ass_ids = array_values(array_unique(array_filter(array_map(
            fn($v) => (int)trim($v),
            $booking['ass_parts']
        ))));
        $booking['assessment_map'] = (object)[];
        if ($ass_ids) {
            $ph   = implode(',', array_fill(0, count($ass_ids), '?'));
            $stmt = $db->prepare("SELECT record_id, assessments_name FROM assessments WHERE record_id IN ($ph)");
            $stmt->execute($ass_ids);
            $map = [];
            while ($row = $stmt->fetch()) { $map[(string)$row['record_id']] = $row; }
            $booking['assessment_map'] = $map;
        }

        // Collect unique test IDs for lookup
        $test_ids = array_values(array_unique(array_filter(array_map(
            fn($v) => (int)trim($v),
            $booking['test_parts']
        ))));
        $booking['test_map'] = (object)[];
        if ($test_ids) {
            $ph   = implode(',', array_fill(0, count($test_ids), '?'));
            $stmt = $db->prepare("SELECT record_id, test_name FROM tests WHERE record_id IN ($ph)");
            $stmt->execute($test_ids);
            $map = [];
            while ($row = $stmt->fetch()) { $map[(string)$row['record_id']] = $row; }
            $booking['test_map'] = $map;
        }

        // Sites for the client (for the edit dropdowns)
        $sites_stmt = $db->prepare('SELECT record_id, client_sites_name FROM client_sites WHERE clients_id = ? ORDER BY client_sites_name ASC');
        $sites_stmt->execute([$booking['clients_id']]);
        $booking['client_sites_list'] = $sites_stmt->fetchAll();

        json_success(['booking' => $booking]);
        break;

    case 'create':
        $date      = trim($_POST['date_booked'] ?? date('Y-m-d H:i'));
        $assessor  = (int)($_POST['safesure_users_id'] ?? $user['record_id']);
        $client    = (int)($_POST['clients_id'] ?? 0);
        $employees = trim($_POST['client_employees'] ?? '');
        $assessments = trim($_POST['assessments'] ?? '');
        $tests     = trim($_POST['tests'] ?? '');
        $notes     = trim($_POST['notes'] ?? '');
        $sites     = trim($_POST['client_sites'] ?? '');
        $status    = 'DRAFT';
        if (!$client) json_error('Client required');

        // Auto booking number
        $max = (int)$db->query('SELECT MAX(booking_number) FROM bookings')->fetchColumn();
        $db->prepare(
            'INSERT INTO bookings (date_booked,safesure_users_id,clients_id,client_employees,assessments,tests,status,notes,client_sites,booking_number)
             VALUES (?,?,?,?,?,?,?,?,?,?)'
        )->execute([$date,$assessor,$client,$employees,$assessments,$tests,$status,$notes,$sites,$max+1]);
        json_success(['id' => $db->lastInsertId()], 'Booking created');
        break;

    case 'update':
        if (!$id) json_error('ID required');
        $sets = []; $vals = [];
        $editable = ['date_booked','safesure_users_id','clients_id','client_employees','assessments','tests','notes','client_sites','status'];
        foreach ($editable as $f) {
            if (isset($_POST[$f])) { $sets[] = "$f=?"; $vals[] = $_POST[$f]; }
        }
        if (empty($sets)) json_error('Nothing to update');
        $vals[] = $id;
        $db->prepare('UPDATE bookings SET ' . implode(',', $sets) . ' WHERE record_id=?')->execute($vals);
        json_success([], 'Booking updated');
        break;

    case 'approve':
        require_admin($user);
        if (!$id) json_error('ID required');
        $db->prepare("UPDATE bookings SET status='APPROVED', date_approved=? WHERE record_id=?")->execute([date('Y-m-d H:i'), $id]);
        json_success([], 'Booking approved');
        break;

    case 'reject':
        require_admin($user);
        if (!$id) json_error('ID required');
        $db->prepare("UPDATE bookings SET status='REJECTED' WHERE record_id=?")->execute([$id]);
        json_success([], 'Booking rejected');
        break;

    case 'complete':
        if (!$id) json_error('ID required');
        $db->prepare("UPDATE bookings SET status='COMPLETE', date_done=? WHERE record_id=?")->execute([date('Y-m-d H:i'), $id]);
        json_success([], 'Booking completed');
        break;

    case 'delete':
        require_admin($user);
        if (!$id) json_error('ID required');
        $db->prepare('DELETE FROM bookings WHERE record_id=?')->execute([$id]);
        json_success([], 'Booking deleted');
        break;

    case 'statuses':
        json_success(['statuses' => ['DRAFT','APPROVED','REJECTED','COMPLETE','NOT APPROVED']]);
        break;

    default:
        json_error('Unknown action');
}
} catch (Throwable $e) {
    json_error('DB error: ' . $e->getMessage() . ' in ' . basename($e->getFile()) . ':' . $e->getLine(), 500);
}