<?php

$tokenRec = require_valid_token_web();

$validTypes = ['question', 'answer_option', 'string', 'app_string', 'language'];

switch ($method) {

case 'GET':
    if (!empty($_GET['exportBundle'])) {
        require_role(['admin', 'supervisor'], $tokenRec);
        try {
            $opened = qdb_open_read_or_fail();
            [$pdo, $tmpDb, $lockFp] = $opened;
            $bundle = qdb_export_translations_bundle($pdo);
            qdb_discard($tmpDb, $lockFp);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Export translations', null, $tmpDb ?? null, $lockFp ?? null);
        }

        $filename = 'translations_bundle_' . date('Y-m-d_His') . '.json';
        qdb_http_download(
            json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
            [
                'Content-Type'        => 'application/json; charset=UTF-8',
                'Content-Disposition' => 'attachment; filename="' . $filename . '"',
            ]
        );
    }

    if (isset($_GET['languages'])) {
        try {
            $opened = qdb_open_read_or_fail();
            [$pdo, $tmpDb, $lockFp] = $opened;
            $rows = $pdo->query("SELECT languageCode, name FROM language ORDER BY languageCode")->fetchAll(PDO::FETCH_ASSOC);
            qdb_discard($tmpDb, $lockFp);
            json_success(['languages' => $rows]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Load languages', null, $tmpDb ?? null, $lockFp ?? null);
        }
    }

    if (!empty($_GET['all'])) {
        try {
            $opened = qdb_open_read_or_fail();
            [$pdo, $tmpDb, $lockFp] = $opened;

        $languages = $pdo->query("SELECT languageCode, name FROM language ORDER BY languageCode")->fetchAll(PDO::FETCH_ASSOC);
        if (!array_filter($languages, fn($l) => $l['languageCode'] === QDB_SOURCE_LANGUAGE)) {
            array_unshift($languages, ['languageCode' => QDB_SOURCE_LANGUAGE, 'name' => 'German']);
        }

        $qnRows = $pdo->query("
            SELECT questionnaireID, name, orderIndex FROM questionnaire ORDER BY orderIndex
        ")->fetchAll(PDO::FETCH_ASSOC);

        $appEntries = qdb_app_ui_string_entries_for_website($pdo);
        $appTranslations = qdb_load_translations_for_entries($pdo, $appEntries);
        qdb_attach_translation_texts($appEntries, $appTranslations);

        $questionnaires = [];
        $allEntries = $appEntries;

        foreach ($qnRows as $qn) {
            $lists = qdb_translation_entry_lists($pdo, $qn['questionnaireID']);
            $entries = array_merge($lists['stringEntries'], $lists['contentEntries']);
            if (!$entries) {
                continue;
            }
            $translations = qdb_load_translations_for_entries($pdo, $entries);
            qdb_attach_translation_texts($entries, $translations);
            $questionnaires[] = [
                'questionnaireID' => $qn['questionnaireID'],
                'name'            => $qn['name'],
                'orderIndex'      => (int)$qn['orderIndex'],
                'entries'         => $entries,
            ];
            foreach ($entries as $e) {
                $allEntries[] = $e;
            }
        }

            qdb_discard($tmpDb, $lockFp);
            json_success([
                'languages'       => $languages,
                'appStrings'      => $appEntries,
                'questionnaires'  => $questionnaires,
                'entries'         => $allEntries,
                'sourceLanguage'  => QDB_SOURCE_LANGUAGE,
            ]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Load translations', null, $tmpDb ?? null, $lockFp ?? null);
        }
    }

    $qnID = trim((string)($_GET['questionnaireID'] ?? ''));
    if ($qnID !== '') {
        try {
            $opened = qdb_open_read_or_fail();
            [$pdo, $tmpDb, $lockFp] = $opened;

            $languages = $pdo->query("SELECT languageCode, name FROM language ORDER BY languageCode")->fetchAll(PDO::FETCH_ASSOC);
            if (!array_filter($languages, fn($l) => $l['languageCode'] === QDB_SOURCE_LANGUAGE)) {
                array_unshift($languages, ['languageCode' => QDB_SOURCE_LANGUAGE, 'name' => 'German']);
            }

            $qnRow = $pdo->prepare('SELECT name FROM questionnaire WHERE questionnaireID = :id');
            $qnRow->execute([':id' => $qnID]);
            $qnName = $qnRow->fetchColumn();
            if ($qnName === false) {
                qdb_discard($tmpDb, $lockFp);
                json_error('NOT_FOUND', 'Questionnaire not found', 404);
            }

            $lists = qdb_translation_entry_lists($pdo, $qnID);
        $entries = array_merge($lists['stringEntries'], $lists['contentEntries']);
        $translations = qdb_load_translations_for_entries($pdo, $entries);
        qdb_attach_translation_texts($entries, $translations);

            qdb_discard($tmpDb, $lockFp);
            json_success([
                'languages'      => $languages,
                'entries'        => $entries,
                'questionnaire'  => ['questionnaireID' => $qnID, 'name' => (string)$qnName],
                'sourceLanguage' => QDB_SOURCE_LANGUAGE,
            ]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Load translations', null, $tmpDb ?? null, $lockFp ?? null);
        }
    }

    $type = $_GET['type'] ?? '';
    $id   = $_GET['id']   ?? '';
    if (!in_array($type, $validTypes, true) || (!$id && $type !== 'string')) {
        json_error('BAD_REQUEST', 'type (question|answer_option|string) and id required', 400);
    }

    try {
        $opened = qdb_open_read_or_fail();
        [$pdo, $tmpDb, $lockFp] = $opened;
        if ($type === 'question') {
        $stmt = $pdo->prepare("SELECT languageCode, text FROM question_translation WHERE questionID = :id");
        $stmt->execute([':id' => $id]);
    } elseif ($type === 'answer_option') {
        $stmt = $pdo->prepare("SELECT languageCode, text FROM answer_option_translation WHERE answerOptionID = :id");
        $stmt->execute([':id' => $id]);
    } else {
        if ($id) {
            $stmt = $pdo->prepare("SELECT stringKey, languageCode, text FROM string_translation WHERE stringKey = :id");
            $stmt->execute([':id' => $id]);
        } else {
            $stmt = $pdo->query("SELECT stringKey, languageCode, text FROM string_translation ORDER BY stringKey, languageCode");
        }
    }
        if ($type === 'question' || $type === 'answer_option') {
            if (!qdb_translation_entity_exists($pdo, $type, (string)$id)) {
                qdb_discard($tmpDb, $lockFp);
                json_error('NOT_FOUND', 'Translation entity not found', 404);
            }
        }

        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        qdb_discard($tmpDb, $lockFp);
        json_success(['translations' => $rows]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Load translations', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

case 'POST':
    require_role(['admin', 'supervisor'], $tokenRec);
    $body = read_json_body();
    if (($body['action'] ?? '') === 'importBundle') {
        $bundle = $body['bundle'] ?? null;
        if (!is_array($bundle)) {
            json_error('MISSING_FIELDS', 'bundle object is required', 400);
        }
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $result = qdb_import_translations_bundle($pdo, $bundle);
            qdb_save($tmpDb, $lockFp);
            json_success($result);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Import translations', null, $tmpDb, $lockFp);
        }
        break;
    }
    if (($body['action'] ?? '') === 'deleteAll') {
        require_role(['admin'], $tokenRec);
        $phrase = trim((string)($body['confirmPhrase'] ?? ''));
        if ($phrase !== 'DELETE ALL TRANSLATIONS') {
            json_error('CONFIRMATION_REQUIRED', 'Type DELETE ALL TRANSLATIONS to confirm', 400);
        }
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $result = qdb_delete_all_translations($pdo, true);
            qdb_save($tmpDb, $lockFp);
            json_success($result);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Delete all translations', null, $tmpDb, $lockFp);
        }
        break;
    }
    json_error('BAD_REQUEST', 'Unknown action', 400);
    break;

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

    if ($type === 'language') {
        $lang = trim($body['languageCode'] ?? '');
        $name = trim($body['name'] ?? '');
        if (!$lang) {
            json_error('MISSING_FIELDS', 'languageCode required', 400);
        }
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            if ($lang === QDB_SOURCE_LANGUAGE) {
                qdb_ensure_source_language($pdo);
            } else {
                $pdo->prepare("INSERT INTO language (languageCode, name) VALUES (:lc, :n)
                               ON CONFLICT(languageCode) DO UPDATE SET name = excluded.name")
                    ->execute([':lc' => $lang, ':n' => $name]);
            }
            qdb_save($tmpDb, $lockFp);
            json_success([]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Save language', null, $tmpDb, $lockFp);
        }
        break;
    }

    $id   = $body['id']   ?? '';
    $lang = trim($body['languageCode'] ?? '');
    $text = $body['text'] ?? '';
    if (!in_array($type, $validTypes, true) || !$id || !$lang) {
        json_error('MISSING_FIELDS', 'type, id, and languageCode required', 400);
    }

    try {
        $opened = qdb_open_write_or_fail();
        [$pdo, $tmpDb, $lockFp] = $opened;
        if (!qdb_translation_entity_exists($pdo, $type, (string)$id)) {
            qdb_discard($tmpDb, $lockFp);
            json_error('NOT_FOUND', 'Translation entity not found', 404);
        }
        qdb_put_translation($pdo, $type, $id, $lang, $text);
        qdb_save($tmpDb, $lockFp);
        json_success([]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Save translation', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

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

    if ($type === 'language') {
        $lang = trim($body['languageCode'] ?? '');
        if (!$lang) {
            json_error('MISSING_FIELDS', 'languageCode required', 400);
        }
        if ($lang === QDB_SOURCE_LANGUAGE) {
            json_error('BAD_REQUEST', 'German (de) cannot be removed', 400);
        }
        [$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
        try {
            $pdo->prepare("DELETE FROM language WHERE languageCode = :lc")->execute([':lc' => $lang]);
            $pdo->prepare("DELETE FROM question_translation WHERE languageCode = :lc")->execute([':lc' => $lang]);
            $pdo->prepare("DELETE FROM answer_option_translation WHERE languageCode = :lc")->execute([':lc' => $lang]);
            $pdo->prepare("DELETE FROM string_translation WHERE languageCode = :lc")->execute([':lc' => $lang]);
            qdb_save($tmpDb, $lockFp);
            json_success([]);
        } catch (Throwable $e) {
            qdb_handler_fail($e, 'Delete language', null, $tmpDb, $lockFp);
        }
        break;
    }

    $id   = $body['id']   ?? '';
    $lang = trim($body['languageCode'] ?? '');
    if (!in_array($type, $validTypes, true) || !$id || !$lang) {
        json_error('MISSING_FIELDS', 'type, id, and languageCode required', 400);
    }

    try {
        $opened = qdb_open_write_or_fail();
        [$pdo, $tmpDb, $lockFp] = $opened;
        if ($type === 'question' || $type === 'answer_option') {
            if (!qdb_translation_entity_exists($pdo, $type, (string)$id)) {
                qdb_discard($tmpDb, $lockFp);
                json_error('NOT_FOUND', 'Translation entity not found', 404);
            }
        }
        if ($type === 'question') {
            $pdo->prepare('DELETE FROM question_translation WHERE questionID = :id AND languageCode = :lang')
                ->execute([':id' => $id, ':lang' => $lang]);
        } elseif ($type === 'answer_option') {
            $pdo->prepare('DELETE FROM answer_option_translation WHERE answerOptionID = :id AND languageCode = :lang')
                ->execute([':id' => $id, ':lang' => $lang]);
        } else {
            $pdo->prepare('DELETE FROM string_translation WHERE stringKey = :id AND languageCode = :lang')
                ->execute([':id' => $id, ':lang' => $lang]);
        }
        qdb_save($tmpDb, $lockFp);
        json_success([]);
    } catch (Throwable $e) {
        qdb_handler_fail($e, 'Delete translation', null, $tmpDb ?? null, $lockFp ?? null);
    }
    break;

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