<?php

$tokenRec = require_valid_token_web();

switch ($method) {

case 'GET':
    try {
        $opened = qdb_open_read_or_fail();
        [$pdo, $tmpDb, $lockFp] = $opened;
        [$rbacClause, $rbacParams] = rbac_client_filter($tokenRec, 'cl');
        $sql = "
            SELECT q.questionnaireID, q.name, q.version, q.state,
                   q.orderIndex, q.showPoints, q.conditionJson, q.categoryKey,
                   COUNT(qu.questionID) AS questionCount,
                   (
                       SELECT COUNT(*)
                       FROM completed_questionnaire cq
                       INNER JOIN client cl ON cl.clientCode = cq.clientCode
                       WHERE cq.questionnaireID = q.questionnaireID
                         AND $rbacClause
                   ) AS completedCount,
                   (
                       SELECT COUNT(*)
                       FROM questionnaire_submission qs
                       INNER JOIN client cl ON cl.clientCode = qs.clientCode
                       WHERE qs.questionnaireID = q.questionnaireID
                         AND $rbacClause
                   ) AS submissionCount
            FROM questionnaire q
            LEFT JOIN question qu ON qu.questionnaireID = q.questionnaireID
            GROUP BY q.questionnaireID
            ORDER BY q.orderIndex, q.name
        ";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($rbacParams);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach ($rows as &$r) {
            $r['orderIndex']  = (int)$r['orderIndex'];
            $r['showPoints']  = (int)$r['showPoints'];
            $r['questionCount'] = (int)$r['questionCount'];
            $r['completedCount'] = (int)$r['completedCount'];
            $r['submissionCount'] = (int)$r['submissionCount'];
            $r['conditionJson'] = $r['conditionJson'] ?: '{}';
        }
        unset($r);
        $categoryKeys = qdb_list_category_keys_for_dashboard($pdo);
        qdb_discard($tmpDb, $lockFp);
        json_success(['questionnaires' => $rows, 'categoryKeys' => $categoryKeys]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Load questionnaires', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'POST':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();

    if (($body['action'] ?? '') === 'updateConditionMessageLabel') {
        $messageKey = trim((string)($body['messageKey'] ?? ''));
        $germanLabel = (string)($body['germanLabel'] ?? '');
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            qdb_set_app_string_german_label($pdo, $messageKey, $germanLabel);
            qdb_save($tmpDb, $lockFp);
            json_success([
                'messageKey'   => qdb_validate_stable_key($messageKey, 'messageKey'),
                'germanLabel'  => trim($germanLabel),
            ]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Update condition message label', null, $tmpDb, $lockFp);
        }
        break;
    }

    if (($body['action'] ?? '') === 'updateCategoryLabel') {
        $categoryKey = trim((string)($body['categoryKey'] ?? ''));
        $germanLabel = (string)($body['germanLabel'] ?? '');
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $stringKey = qdb_set_category_german_label($pdo, $categoryKey, $germanLabel);
            qdb_save($tmpDb, $lockFp);
            json_success([
                'categoryKey'  => $categoryKey,
                'stringKey'    => $stringKey,
                'germanLabel'  => trim($germanLabel),
            ]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Update category label', null, $tmpDb, $lockFp);
        }
        break;
    }

    if (($body['action'] ?? '') === 'deleteCategoryKey') {
        $categoryKey = trim((string)($body['categoryKey'] ?? ''));
        if ($categoryKey === '') {
            json_error('INVALID_FIELD', 'categoryKey is required', 400);
        }
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $cleared = qdb_delete_category_key($pdo, $categoryKey);
            qdb_save($tmpDb, $lockFp);
            json_success(['deleted' => $categoryKey, 'questionnairesCleared' => $cleared]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Delete category key', null, $tmpDb, $lockFp);
        }
        break;
    }

    if (($body['action'] ?? '') === 'importBundle') {
        $bundle = $body['bundle'] ?? null;
        if (!is_array($bundle)) {
            json_error('MISSING_FIELDS', 'bundle object is required', 400);
        }
        $replaceIfExists = !empty($body['replaceIfExists']);
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $pdo->exec('PRAGMA foreign_keys = OFF;');
            $result = qdb_import_questionnaires_bundle($pdo, $bundle, $replaceIfExists);
            $pdo->exec('PRAGMA foreign_keys = ON;');
            qdb_save($tmpDb, $lockFp);
            json_success($result);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Import questionnaires', null, $tmpDb, $lockFp);
        }
        break;
    }

    if (empty($body['name'])) {
        json_error('NAME_REQUIRED', 'name is required', 400);
    }
    $id        = bin2hex(random_bytes(16));
    $name      = trim($body['name']);
    $version   = trim($body['version'] ?? '');
    $state     = trim($body['state'] ?? 'draft');
    $order     = (int)($body['orderIndex'] ?? 0);
    $showPts   = (int)($body['showPoints'] ?? 0);
    $condJson  = $body['conditionJson'] ?? '{}';

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        if ($order === 0) {
            $order = (int)$pdo->query("SELECT COALESCE(MAX(orderIndex),0)+1 FROM questionnaire")->fetchColumn();
        }
        $catKey = trim($body['categoryKey'] ?? '');
        if ($catKey !== '') {
            $catKey = qdb_normalize_stable_key($catKey);
        }
        $pdo->prepare("INSERT INTO questionnaire (questionnaireID, name, version, state, orderIndex, showPoints, conditionJson, categoryKey)
                        VALUES (:id, :n, :v, :s, :o, :sp, :cj, :ck)")
            ->execute([':id' => $id, ':n' => $name, ':v' => $version, ':s' => $state,
                       ':o' => $order, ':sp' => $showPts, ':cj' => $condJson, ':ck' => $catKey]);
        qdb_save($tmpDb, $lockFp);
        json_success(['questionnaire' => [
            'questionnaireID' => $id, 'name' => $name, 'version' => $version,
            'state' => $state, 'orderIndex' => $order, 'showPoints' => $showPts,
            'conditionJson' => $condJson, 'questionCount' => 0,
        ]]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Create questionnaire', null, $tmpDb, $lockFp);
    }
    break;

case 'PUT':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    if (empty($body['questionnaireID'])) {
        json_error('QUESTIONNAIRE_ID_REQUIRED', 'questionnaireID is required', 400);
    }
    $id = $body['questionnaireID'];

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $existing = $pdo->prepare('SELECT * FROM questionnaire WHERE questionnaireID = :id');
        $existing->execute([':id' => $id]);
        $row = $existing->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Questionnaire not found', 404);
        }
        $name    = trim($body['name']    ?? $row['name']);
        $version = trim($body['version'] ?? $row['version']);
        $state   = trim($body['state']   ?? $row['state']);
        $order   = (int)($body['orderIndex']  ?? $row['orderIndex']);
        $showPts = (int)($body['showPoints']  ?? $row['showPoints']);
        $condJson = $body['conditionJson']    ?? $row['conditionJson'];
        $catKey   = array_key_exists('categoryKey', $body)
            ? trim((string)$body['categoryKey'])
            : trim($row['categoryKey'] ?? '');
        if ($catKey !== '') {
            $catKey = qdb_normalize_stable_key($catKey);
        }

        $pdo->prepare("UPDATE questionnaire SET name = :n, version = :v, state = :s,
                        orderIndex = :o, showPoints = :sp, conditionJson = :cj, categoryKey = :ck
                        WHERE questionnaireID = :id")
            ->execute([':n' => $name, ':v' => $version, ':s' => $state,
                       ':o' => $order, ':sp' => $showPts, ':cj' => $condJson, ':ck' => $catKey, ':id' => $id]);
        qdb_save($tmpDb, $lockFp);
        json_success(['questionnaire' => [
            'questionnaireID' => $id, 'name' => $name, 'version' => $version, 'state' => $state,
            'orderIndex' => $order, 'showPoints' => $showPts, 'conditionJson' => $condJson,
        ]]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Update questionnaire', null, $tmpDb, $lockFp);
    }
    break;

case 'DELETE':
    require_role(['admin'], $tokenRec);
    $body = read_json_body();
    if (empty($body['questionnaireID'])) {
        json_error('QUESTIONNAIRE_ID_REQUIRED', 'questionnaireID is required', 400);
    }
    $id = $body['questionnaireID'];

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $pdo->exec('PRAGMA foreign_keys = OFF;');
        $pdo->beginTransaction();

        $qIds = $pdo->prepare('SELECT questionID FROM question WHERE questionnaireID = :id');
        $qIds->execute([':id' => $id]);
        $questionIDs = $qIds->fetchAll(PDO::FETCH_COLUMN);

        foreach ($questionIDs as $qid) {
            $aoIds = $pdo->prepare('SELECT answerOptionID FROM answer_option WHERE questionID = :qid');
            $aoIds->execute([':qid' => $qid]);
            $optionIDs = $aoIds->fetchAll(PDO::FETCH_COLUMN);
            foreach ($optionIDs as $aoid) {
                $pdo->prepare('DELETE FROM answer_option_translation WHERE answerOptionID = :id')->execute([':id' => $aoid]);
            }
            $pdo->prepare('DELETE FROM answer_option WHERE questionID = :qid')->execute([':qid' => $qid]);
            $pdo->prepare('DELETE FROM question_translation WHERE questionID = :qid')->execute([':qid' => $qid]);
            $pdo->prepare('DELETE FROM client_answer WHERE questionID = :qid')->execute([':qid' => $qid]);
        }
        $pdo->prepare('DELETE FROM question WHERE questionnaireID = :id')->execute([':id' => $id]);
        $pdo->prepare('DELETE FROM completed_questionnaire WHERE questionnaireID = :id')->execute([':id' => $id]);
        $pdo->prepare('DELETE FROM questionnaire WHERE questionnaireID = :id')->execute([':id' => $id]);

        $pdo->commit();
        $pdo->exec('PRAGMA foreign_keys = ON;');
        qdb_save($tmpDb, $lockFp);
        json_success([]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Delete questionnaire', $pdo, $tmpDb, $lockFp);
    }
    break;

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