-- ============================================================================
-- FUNCIÓN: validate_construccion_hipotesis
-- Descripción: Validador heurístico para construcción de hipótesis (Módulo 2)
-- Autor: Database Agent
-- Fecha: 2025-11-19
-- Tarea: DB-116
-- ============================================================================

CREATE OR REPLACE FUNCTION educational_content.validate_construccion_hipotesis(
    p_solution JSONB,
    p_submitted_answer JSONB,
    p_max_points INTEGER,
    p_fuzzy_threshold NUMERIC DEFAULT 0.70,
    p_normalize_text BOOLEAN DEFAULT true,
    p_special_rules JSONB DEFAULT '{}'::jsonb,
    OUT is_correct BOOLEAN,
    OUT score INTEGER,
    OUT feedback TEXT,
    OUT details JSONB
)
RETURNS RECORD
LANGUAGE plpgsql
IMMUTABLE
AS $$
DECLARE
    v_hypothesis TEXT;
    v_keywords JSONB;
    v_min_words INTEGER;
    v_word_count INTEGER;
    v_keywords_found INTEGER := 0;
    v_total_keywords INTEGER;
    v_keyword TEXT;
    v_normalized_hypothesis TEXT;
    v_keyword_threshold NUMERIC;
BEGIN
    -- Extraer hipótesis enviada
    v_hypothesis := p_submitted_answer->>'hypothesis';

    IF v_hypothesis IS NULL OR TRIM(v_hypothesis) = '' THEN
        is_correct := false;
        score := 0;
        feedback := 'No se proporcionó ninguna hipótesis.';
        details := jsonb_build_object('error', 'empty_hypothesis');
        RETURN;
    END IF;

    -- Extraer configuración
    v_keywords := p_solution->'keywords';
    v_min_words := COALESCE((p_solution->>'min_words')::integer, (p_special_rules->>'min_word_count')::integer, 20);
    v_keyword_threshold := COALESCE((p_special_rules->>'keywords_threshold')::numeric, 0.60);

    -- Contar palabras
    v_word_count := array_length(string_to_array(TRIM(v_hypothesis), ' '), 1);

    -- Normalizar texto
    IF p_normalize_text THEN
        v_normalized_hypothesis := LOWER(gamilit.normalize_text(v_hypothesis));
    ELSE
        v_normalized_hypothesis := LOWER(v_hypothesis);
    END IF;

    -- Contar keywords encontradas
    IF v_keywords IS NOT NULL THEN
        v_total_keywords := jsonb_array_length(v_keywords);

        FOR v_keyword IN SELECT jsonb_array_elements_text(v_keywords)
        LOOP
            IF p_normalize_text THEN
                v_keyword := LOWER(gamilit.normalize_text(v_keyword));
            ELSE
                v_keyword := LOWER(v_keyword);
            END IF;

            IF v_normalized_hypothesis LIKE '%' || v_keyword || '%' THEN
                v_keywords_found := v_keywords_found + 1;
            END IF;
        END LOOP;
    ELSE
        v_total_keywords := 0;
    END IF;

    -- Calcular score heurístico
    -- 50% por longitud mínima + 50% por keywords
    IF v_word_count >= v_min_words THEN
        score := p_max_points / 2;
    ELSE
        score := ROUND((v_word_count::NUMERIC / v_min_words) * (p_max_points / 2));
    END IF;

    IF v_total_keywords > 0 THEN
        IF (v_keywords_found::NUMERIC / v_total_keywords) >= v_keyword_threshold THEN
            score := score + (p_max_points / 2);
        ELSE
            score := score + ROUND((v_keywords_found::NUMERIC / v_total_keywords) * (p_max_points / 2));
        END IF;
    END IF;

    is_correct := (score >= (p_max_points * 0.70));

    -- Feedback
    IF is_correct THEN
        feedback := format('Buena hipótesis. Longitud: %s palabras. Keywords encontradas: %s/%s.',
                          v_word_count, v_keywords_found, v_total_keywords);
    ELSE
        feedback := format('Hipótesis incompleta. Necesitas al menos %s palabras (tienes %s) y más keywords clave.',
                          v_min_words, v_word_count);
    END IF;

    -- Details
    details := jsonb_build_object(
        'word_count', v_word_count,
        'min_words_required', v_min_words,
        'keywords_found', v_keywords_found,
        'total_keywords', v_total_keywords,
        'validation_type', 'heuristic'
    );
END;
$$;

COMMENT ON FUNCTION educational_content.validate_construccion_hipotesis IS
'Validador heurístico para construcción de hipótesis (Módulo 2).
Verifica longitud mínima y presencia de palabras clave.
NO valida calidad real del contenido - solo criterios básicos.';
