<?php
/**
 * Program session CRUD — define which questionnaires belong to each session.
 */

require_once __DIR__ . '/../lib/program_sessions.php';

$tokenRec = require_valid_token_web();

switch ($method) {
case 'GET':
    try {
        [$pdo, $tmpDb, $lockFp] = qdb_open_read_or_fail();
        $sessionID = trim($_GET['id'] ?? '');
        if ($sessionID !== '') {
            $session = qdb_get_program_session($pdo, $sessionID);
            qdb_discard($tmpDb, $lockFp);
            if (!$session) {
                json_error('NOT_FOUND', 'Session not found', 404);
            }
            json_success([
                'session'  => $session,
                'settings' => qdb_program_session_settings_get($pdo),
            ]);
        }
        json_success([
            'sessions' => qdb_list_program_sessions($pdo),
            'settings' => qdb_program_session_settings_get($pdo),
        ]);
        qdb_discard($tmpDb, $lockFp);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'List program sessions', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'POST':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    $name = trim($body['name'] ?? '');
    if ($name === '') {
        json_error('BAD_REQUEST', 'name is required', 400);
    }
    $members = qdb_parse_program_session_questionnaires($body['questionnaires'] ?? []);
    try {
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        $order = qdb_program_session_resolve_order($pdo, $body);
        $sessionNumber = $order['sessionNumber'];
        $orderIndex = $order['orderIndex'];
        $err = qdb_validate_program_session_questionnaires($pdo, $members);
        if ($err !== null) {
            qdb_discard($tmpDb, $lockFp);
            json_error('INVALID_FIELD', $err, 400);
        }
        $sessionID = bin2hex(random_bytes(16));
        $now = time();
        $pdo->prepare(
            'INSERT INTO program_session
             (sessionID, name, description, sessionNumber, orderIndex, isActive, createdAt, updatedAt)
             VALUES (:id, :name, :desc, :num, :ord, :act, :ca, :ua)'
        )->execute([
            ':id'   => $sessionID,
            ':name' => $name,
            ':desc' => trim($body['description'] ?? ''),
            ':num'  => $sessionNumber,
            ':ord'  => $orderIndex,
            ':act'  => !empty($body['isActive']) || !array_key_exists('isActive', $body) ? 1 : 0,
            ':ca'   => $now,
            ':ua'   => $now,
        ]);
        qdb_sync_program_session_questionnaires($pdo, $sessionID, $members);
        qdb_save($tmpDb, $lockFp);
        json_success(['session' => qdb_get_program_session($pdo, $sessionID)]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Create program session', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'PUT':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    $sessionID = trim($body['sessionID'] ?? '');
    if ($sessionID === '') {
        json_error('BAD_REQUEST', 'sessionID is required', 400);
    }
    try {
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        $existing = qdb_get_program_session($pdo, $sessionID);
        if (!$existing) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Session not found', 404);
        }
        $name = trim($body['name'] ?? $existing['name']);
        if ($name === '') {
            qdb_discard($tmpDb, $lockFp);
            json_error('BAD_REQUEST', 'name is required', 400);
        }
        $members = array_key_exists('questionnaires', $body)
            ? qdb_parse_program_session_questionnaires($body['questionnaires'])
            : null;
        if ($members !== null) {
            $err = qdb_validate_program_session_questionnaires($pdo, $members);
            if ($err !== null) {
                qdb_discard($tmpDb, $lockFp);
                json_error('INVALID_FIELD', $err, 400);
            }
        }
        $order = qdb_program_session_resolve_order($pdo, $body, $existing);
        $pdo->prepare(
            'UPDATE program_session SET
                name = :name,
                description = :desc,
                sessionNumber = :num,
                orderIndex = :ord,
                isActive = :act,
                updatedAt = :ua
             WHERE sessionID = :id'
        )->execute([
            ':name' => $name,
            ':desc' => trim($body['description'] ?? $existing['description']),
            ':num'  => $order['sessionNumber'],
            ':ord'  => $order['orderIndex'],
            ':act'  => isset($body['isActive'])
                ? (!empty($body['isActive']) ? 1 : 0)
                : $existing['isActive'],
            ':ua'   => time(),
            ':id'   => $sessionID,
        ]);
        if ($members !== null) {
            qdb_sync_program_session_questionnaires($pdo, $sessionID, $members);
        }
        qdb_save($tmpDb, $lockFp);
        json_success(['session' => qdb_get_program_session($pdo, $sessionID)]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Update program session', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'PATCH':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    try {
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        $settings = qdb_program_session_settings_save($pdo, $body);
        qdb_save($tmpDb, $lockFp);
        json_success(['settings' => $settings]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Update program session settings', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'DELETE':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    $sessionID = trim($body['sessionID'] ?? '');
    if ($sessionID === '') {
        json_error('BAD_REQUEST', 'sessionID is required', 400);
    }
    try {
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        $pdo->prepare('DELETE FROM program_session WHERE sessionID = :id')->execute([':id' => $sessionID]);
        qdb_save($tmpDb, $lockFp);
        json_success(['deleted' => true]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Delete program session', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

default:
    json_error('METHOD_NOT_ALLOWED', 'Method not allowed', 405);
}
