<?php

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

$tokenRec = require_valid_token_web();
$method   = $_SERVER['REQUEST_METHOD'];

switch ($method) {

case 'GET':
    $qID = $_GET['questionID'] ?? '';
    if (!$qID) {
        json_error('MISSING_PARAM', 'questionID query param required', 400);
    }
    try {
        $opened = qdb_open_read_or_fail();
        [$pdo, $tmpDb, $lockFp] = $opened;
        $stmt = $pdo->prepare('SELECT answerOptionID, questionID, defaultText, points, orderIndex, nextQuestionId FROM answer_option WHERE questionID = :qid ORDER BY orderIndex');
        $stmt->execute([':qid' => $qID]);
        $options = $stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach ($options as &$o) {
            $o['points']     = (int)$o['points'];
            $o['orderIndex'] = (int)$o['orderIndex'];
            $o['optionKey'] = qdb_option_key($o);
            $o['labelGerman'] = qdb_option_german_label($pdo, $o['answerOptionID'], $o['defaultText']);
            $tr = $pdo->prepare('SELECT languageCode, text FROM answer_option_translation WHERE answerOptionID = :id');
            $tr->execute([':id' => $o['answerOptionID']]);
            $o['translations'] = $tr->fetchAll(PDO::FETCH_ASSOC);
        }
        unset($o);
        qdb_discard($tmpDb, $lockFp);
        json_success(['answerOptions' => $options]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Load answer options', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'POST':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    if (empty($body['questionID']) || empty($body['optionKey']) || !isset($body['defaultText'])) {
        json_error('MISSING_FIELDS', 'questionID, optionKey, and defaultText (German label) required', 400);
    }
    $id   = bin2hex(random_bytes(16));
    $qID  = $body['questionID'];
    $optKey = qdb_validate_stable_key((string)$body['optionKey'], 'Option key');
    $text = trim($body['defaultText']);
    qdb_require_non_empty_german($text, 'German label');
    $points = (int)($body['points'] ?? 0);
    $order  = (int)($body['orderIndex'] ?? 0);
    $nextQ  = trim($body['nextQuestionId'] ?? '');

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $chk = $pdo->prepare('SELECT questionnaireID FROM question WHERE questionID = :id');
        $chk->execute([':id' => $qID]);
        $qnID = $chk->fetchColumn();
        if (!$qnID) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Question not found', 404);
        }
        $qnID = (string)$qnID;
        if ($order === 0) {
            $max = $pdo->prepare('SELECT COALESCE(MAX(orderIndex),0)+1 FROM answer_option WHERE questionID = :id');
            $max->execute([':id' => $qID]);
            $order = (int)$max->fetchColumn();
        }
        qdb_assert_unique_option_key($pdo, $qID, $optKey);
        $pdo->prepare('INSERT INTO answer_option (answerOptionID, questionID, defaultText, points, orderIndex, nextQuestionId) VALUES (:id, :qid, :t, :p, :o, :nq)')
            ->execute([':id' => $id, ':qid' => $qID, ':t' => $optKey, ':p' => $points, ':o' => $order, ':nq' => $nextQ]);
        qdb_upsert_source_translation($pdo, 'answer_option', $id, $text);
        $newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_added');
        qdb_save($tmpDb, $lockFp);
        json_success([
            'structureRevision' => $newRev,
            'answerOption' => [
            'answerOptionID' => $id,
            'questionID'     => $qID,
            'optionKey'      => $optKey,
            'defaultText'    => $optKey,
            'labelGerman'    => $text,
            'points'         => $points,
            'orderIndex'     => $order,
            'nextQuestionId' => $nextQ,
            'translations'   => [],
        ]]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Answer options', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

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

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $existing = $pdo->prepare('SELECT * FROM answer_option WHERE answerOptionID = :id');
        $existing->execute([':id' => $id]);
        $row = $existing->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Answer option not found', 404);
        }
        $optKey = isset($body['optionKey'])
            ? qdb_validate_stable_key((string)$body['optionKey'], 'Option key')
            : qdb_option_key($row);
        if ($optKey === '') {
            json_error('MISSING_FIELDS', 'optionKey is required', 400);
        }
        $labelGerman = trim($body['defaultText'] ?? $body['labelGerman'] ?? '');
        if ($labelGerman === '') {
            $labelGerman = qdb_option_german_label($pdo, $id, $row['defaultText']);
        }
        qdb_require_non_empty_german($labelGerman, 'German label');
        qdb_assert_unique_option_key($pdo, $row['questionID'], $optKey, $id);
        $points = (int)($body['points'] ?? $row['points']);
        $order  = (int)($body['orderIndex'] ?? $row['orderIndex']);
        $nextQ  = trim($body['nextQuestionId'] ?? $row['nextQuestionId']);

        $keyChanged = $optKey !== qdb_option_key($row);
        $pdo->prepare('UPDATE answer_option SET defaultText = :t, points = :p, orderIndex = :o, nextQuestionId = :nq WHERE answerOptionID = :id')
            ->execute([':t' => $optKey, ':p' => $points, ':o' => $order, ':nq' => $nextQ, ':id' => $id]);
        qdb_upsert_source_translation($pdo, 'answer_option', $id, $labelGerman);
        $qnID = qdb_questionnaire_id_for_question($pdo, (string)$row['questionID']);
        $newRev = null;
        if ($keyChanged && $qnID !== null) {
            $newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_key_changed');
        }
        qdb_save($tmpDb, $lockFp);
        json_success([
            'structureRevision' => $newRev ?? ($qnID !== null ? qdb_questionnaire_structure_revision($pdo, $qnID) : 1),
            'answerOption' => [
            'answerOptionID' => $id,
            'questionID'     => $row['questionID'],
            'optionKey'      => $optKey,
            'defaultText'    => $optKey,
            'labelGerman'    => $labelGerman,
            'points'         => $points,
            'orderIndex'     => $order,
            'nextQuestionId' => $nextQ,
        ]]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Answer options', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

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

    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $existing = $pdo->prepare('SELECT questionID FROM answer_option WHERE answerOptionID = :id');
        $existing->execute([':id' => $id]);
        $qid = $existing->fetchColumn();
        if (!$qid) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Answer option not found', 404);
        }
        $qnID = qdb_questionnaire_id_for_question($pdo, (string)$qid);
        if ($qnID === null) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Question not found', 404);
        }
        $pdo->beginTransaction();
        $newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_removed');
        if (qdb_option_has_client_data($pdo, $id)) {
            $pdo->prepare('UPDATE answer_option SET retiredAt = :ts WHERE answerOptionID = :id')
                ->execute([':ts' => time(), ':id' => $id]);
            $pdo->commit();
            qdb_save($tmpDb, $lockFp);
            json_success(['deleted' => false, 'retired' => true, 'structureRevision' => $newRev]);
            break;
        }
        qdb_set_foreign_keys($pdo, false);
        $pdo->prepare('DELETE FROM answer_option_translation WHERE answerOptionID = :id')->execute([':id' => $id]);
        $pdo->prepare('DELETE FROM answer_option WHERE answerOptionID = :id')->execute([':id' => $id]);
        qdb_set_foreign_keys($pdo, true);
        $pdo->commit();
        qdb_save($tmpDb, $lockFp);
        json_success(['deleted' => true, 'retired' => false, 'structureRevision' => $newRev]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Delete answer option', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'PATCH':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    if (empty($body['questionID']) || !is_array($body['order'] ?? null)) {
        json_error('MISSING_FIELDS', 'questionID and order[] required', 400);
    }
    [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
    try {
        $stmt = $pdo->prepare('UPDATE answer_option SET orderIndex = :o WHERE answerOptionID = :id AND questionID = :qid');
        foreach ($body['order'] as $idx => $aoid) {
            $stmt->execute([':o' => $idx, ':id' => $aoid, ':qid' => $body['questionID']]);
        }
        qdb_save($tmpDb, $lockFp);
        json_success(['reordered' => true]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Answer options', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

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