function normalizeText(text) {
    if (!text) return '';
    return text
        .toLowerCase()
        .replace(/[äÄ]/g, 'ae')
        .replace(/[öÖ]/g, 'oe')
        .replace(/[üÜ]/g, 'ue')
        .replace(/ß/g, 'ss')
        .replace(/[^a-z0-9]/g, '')
        .trim();
}

function extractFieldValue(field, fallback) {
    if (!field) return fallback || '';
    if (typeof field === 'string') return field;
    if (typeof field === 'object' && field.value !== undefined) return field.value;
    return String(field);
}

function getTyp(question) {
    return extractFieldValue(question['Typ'], 'MC').toLowerCase();
}

function checkFreitext(userAnswer, correctAnswer) {
    return normalizeText(userAnswer) === normalizeText(correctAnswer);
}

/**
 * Resolve correct answer(s) to keys (A/B/C/D).
 * Handles both:
 *   - "A" or "A,C" (key-based)
 *   - "Falsch" or "Stuttgart" (text-based → resolved to matching key)
 */
function parseCorrectAnswers(question) {
    const raw = (question['Richtige Antwort'] || '').trim();
    const typ = getTyp(question);
    if (typ === 'freitext') return [raw];

    const parts = raw.split(',').map((s) => s.trim()).filter(Boolean);
    const validKeys = new Set(['A', 'B', 'C', 'D']);

    // Check if all parts are valid keys already
    const allAreKeys = parts.length > 0 && parts.every((p) => validKeys.has(p.toUpperCase()));
    if (allAreKeys) {
        return parts.map((p) => p.toUpperCase());
    }

    // Otherwise: try to match each part against the answer texts
    const resolved = [];
    for (const part of parts) {
        const partLower = part.toLowerCase().trim();
        const keys = ['A', 'B', 'C', 'D'];
        let found = false;
        for (const k of keys) {
            const answerText = (question[`Antwort ${k}`] || '').trim();
            if (answerText && answerText.toLowerCase() === partLower) {
                resolved.push(k);
                found = true;
                break;
            }
        }
        // If it looks like a key anyway (single char), use it
        if (!found && part.length === 1 && validKeys.has(part.toUpperCase())) {
            resolved.push(part.toUpperCase());
        }
    }

    if (resolved.length > 0) return resolved;

    // Fallback: return as-is uppercase
    return parts.map((p) => p.toUpperCase());
}

function countOptions(question) {
    let n = 0;
    if (question['Antwort A']) n++;
    if (question['Antwort B']) n++;
    if (question['Antwort C']) n++;
    if (question['Antwort D']) n++;
    return n;
}

function shuffleArray(arr) {
    const a = [...arr];
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

function calculateScore(question, selected, timeRemaining, totalTime, scoringMode) {
    if (!selected || selected.length === 0) return { points: 0, correct: false };

    let basis;
    if (scoringMode === 'time' && totalTime > 0) {
        const ratio = Math.max(0, Math.min(1, timeRemaining / totalTime));
        basis = 500 + Math.round(ratio * 500);
    } else {
        basis = 1000;
    }

    const typ = getTyp(question);
    const correctAnswers = parseCorrectAnswers(question);

    if (typ === 'freitext') {
        const ok = checkFreitext(selected[0], correctAnswers[0]);
        return { points: ok ? basis : 0, correct: ok };
    }

    const correctSet = new Set(correctAnswers);
    const totalCorrect = correctSet.size;
    const totalIncorrect = countOptions(question) - totalCorrect;

    let rightPicked = 0;
    let wrongPicked = 0;
    for (const s of selected) {
        if (correctSet.has(s.toUpperCase())) rightPicked++;
        else wrongPicked++;
    }

    let points = (rightPicked / Math.max(totalCorrect, 1)) * basis;
    if (totalIncorrect > 0) {
        points -= (wrongPicked / totalIncorrect) * (basis / 2);
    }
    points = Math.max(0, Math.round(points));

    const fullyCorrect = rightPicked === totalCorrect && wrongPicked === 0;
    return { points, correct: fullyCorrect };
}

function sanitizeQuestion(question) {
    const typ = getTyp(question);
    const sanitized = {
        id: question.id,
        frage: question['Frage'] || '',
        typ: extractFieldValue(question['Typ'], 'MC'),
        bild: null,
        antworten: [],
        kategorie: extractFieldValue(question['Kategorie'], ''),
    };

    const bild = question['Bild'];
    if (bild && Array.isArray(bild) && bild.length > 0 && bild[0].url) {
        sanitized.bild = `/api/img?url=${encodeURIComponent(bild[0].url)}`;
    }

    if (typ !== 'freitext') {
        const keys = ['A', 'B', 'C', 'D'];
        for (const k of keys) {
            const val = question[`Antwort ${k}`];
            if (val) sanitized.antworten.push({ key: k, text: val });
        }
        sanitized.antworten = shuffleArray(sanitized.antworten);
    }

    return sanitized;
}

module.exports = { calculateScore, sanitizeQuestion, parseCorrectAnswers, normalizeText, shuffleArray, extractFieldValue };