-- ============================================================================
-- SCHEMA: education
-- TABLE: quizzes
-- DESCRIPTION: Cuestionarios y evaluaciones
-- VERSION: 1.0.0
-- CREATED: 2026-01-16
-- SPRINT: Sprint 2 - DDL Implementation Roadmap Q1-2026
-- ============================================================================

-- Enum para tipo de quiz
DO $$ BEGIN
    CREATE TYPE education.quiz_type AS ENUM (
        'practice',         -- Quiz de practica (sin limite)
        'graded',           -- Quiz calificado
        'final_exam',       -- Examen final
        'diagnostic',       -- Evaluacion diagnostica
        'survey'            -- Encuesta (sin respuestas correctas)
    );
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;

-- Tabla de Quizzes
CREATE TABLE IF NOT EXISTS education.quizzes (
    -- Identificadores
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    course_id UUID NOT NULL REFERENCES education.courses(id) ON DELETE CASCADE,
    module_id UUID REFERENCES education.modules(id) ON DELETE SET NULL,
    lesson_id UUID REFERENCES education.lessons(id) ON DELETE SET NULL,
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Informacion basica
    title VARCHAR(200) NOT NULL,
    slug VARCHAR(200) NOT NULL,
    description TEXT,
    instructions TEXT,

    -- Tipo
    type education.quiz_type NOT NULL DEFAULT 'practice',

    -- Configuracion
    time_limit_minutes INTEGER,                     -- NULL = sin limite
    passing_score INTEGER NOT NULL DEFAULT 70,      -- Porcentaje minimo para aprobar
    max_attempts INTEGER,                           -- NULL = ilimitado
    shuffle_questions BOOLEAN NOT NULL DEFAULT TRUE,
    shuffle_answers BOOLEAN NOT NULL DEFAULT TRUE,
    show_correct_answers BOOLEAN NOT NULL DEFAULT TRUE,
    show_explanations BOOLEAN NOT NULL DEFAULT TRUE,
    immediate_feedback BOOLEAN NOT NULL DEFAULT FALSE,

    -- Preguntas
    question_count INTEGER NOT NULL DEFAULT 0,
    questions_to_show INTEGER,                      -- NULL = mostrar todas
    points_per_question INTEGER DEFAULT 1,

    -- Estado
    status education.publish_status NOT NULL DEFAULT 'draft',

    -- Disponibilidad
    available_from TIMESTAMPTZ,
    available_until TIMESTAMPTZ,

    -- Requisitos
    requires_lesson_completion BOOLEAN NOT NULL DEFAULT FALSE,
    required_lessons UUID[],                        -- Lecciones que deben completarse antes

    -- Gamificacion
    xp_reward INTEGER DEFAULT 50,
    badge_on_perfect_score UUID,

    -- Estadisticas (cache)
    attempt_count INTEGER NOT NULL DEFAULT 0,
    average_score DECIMAL(5, 2) DEFAULT 0,
    pass_rate DECIMAL(5, 2) DEFAULT 0,

    -- Metadata
    metadata JSONB DEFAULT '{}'::JSONB,

    -- Timestamps
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    -- Constraints
    CONSTRAINT quizzes_unique_slug UNIQUE (course_id, slug),
    CONSTRAINT quizzes_passing_score_check CHECK (passing_score BETWEEN 0 AND 100)
);

COMMENT ON TABLE education.quizzes IS
'Cuestionarios y evaluaciones del sistema educativo';

COMMENT ON COLUMN education.quizzes.questions_to_show IS
'Si es menor que question_count, se seleccionan aleatoriamente';

-- Indices
CREATE INDEX IF NOT EXISTS idx_quizzes_course
    ON education.quizzes(course_id);

CREATE INDEX IF NOT EXISTS idx_quizzes_module
    ON education.quizzes(module_id)
    WHERE module_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_quizzes_lesson
    ON education.quizzes(lesson_id)
    WHERE lesson_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_quizzes_tenant
    ON education.quizzes(tenant_id);

CREATE INDEX IF NOT EXISTS idx_quizzes_type
    ON education.quizzes(type);

CREATE INDEX IF NOT EXISTS idx_quizzes_status
    ON education.quizzes(status);

-- Trigger para updated_at
DROP TRIGGER IF EXISTS quiz_updated_at ON education.quizzes;
CREATE TRIGGER quiz_updated_at
    BEFORE UPDATE ON education.quizzes
    FOR EACH ROW
    EXECUTE FUNCTION education.update_education_timestamp();

-- Trigger para actualizar quiz_count en modulo y curso
CREATE OR REPLACE FUNCTION education.update_quiz_counts()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        IF NEW.module_id IS NOT NULL THEN
            UPDATE education.modules
            SET quiz_count = quiz_count + 1
            WHERE id = NEW.module_id;
        END IF;

        UPDATE education.courses
        SET total_quizzes = total_quizzes + 1
        WHERE id = NEW.course_id;

    ELSIF TG_OP = 'DELETE' THEN
        IF OLD.module_id IS NOT NULL THEN
            UPDATE education.modules
            SET quiz_count = quiz_count - 1
            WHERE id = OLD.module_id;
        END IF;

        UPDATE education.courses
        SET total_quizzes = total_quizzes - 1
        WHERE id = OLD.course_id;
    END IF;

    RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS quiz_counts ON education.quizzes;
CREATE TRIGGER quiz_counts
    AFTER INSERT OR DELETE ON education.quizzes
    FOR EACH ROW
    EXECUTE FUNCTION education.update_quiz_counts();

-- Actualizar lesson.has_quiz cuando se asocia un quiz
CREATE OR REPLACE FUNCTION education.update_lesson_has_quiz()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
        IF NEW.lesson_id IS NOT NULL THEN
            UPDATE education.lessons
            SET has_quiz = TRUE, quiz_id = NEW.id
            WHERE id = NEW.lesson_id;
        END IF;
    END IF;

    IF TG_OP = 'DELETE' OR (TG_OP = 'UPDATE' AND OLD.lesson_id != NEW.lesson_id) THEN
        IF OLD.lesson_id IS NOT NULL THEN
            UPDATE education.lessons
            SET has_quiz = FALSE, quiz_id = NULL
            WHERE id = OLD.lesson_id;
        END IF;
    END IF;

    RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS quiz_lesson_link ON education.quizzes;
CREATE TRIGGER quiz_lesson_link
    AFTER INSERT OR UPDATE OF lesson_id OR DELETE ON education.quizzes
    FOR EACH ROW
    EXECUTE FUNCTION education.update_lesson_has_quiz();

-- Vista de quizzes de un curso
CREATE OR REPLACE VIEW education.v_course_quizzes AS
SELECT
    q.id,
    q.course_id,
    q.module_id,
    q.lesson_id,
    q.title,
    q.type,
    q.time_limit_minutes,
    q.passing_score,
    q.max_attempts,
    q.question_count,
    q.average_score,
    q.pass_rate,
    q.status
FROM education.quizzes q
WHERE q.status = 'published'
ORDER BY q.course_id, q.created_at;

-- RLS Policy para multi-tenancy
ALTER TABLE education.quizzes ENABLE ROW LEVEL SECURITY;

CREATE POLICY quizzes_tenant_isolation ON education.quizzes
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);

-- Grants
GRANT SELECT, INSERT, UPDATE, DELETE ON education.quizzes TO trading_app;
GRANT SELECT ON education.quizzes TO trading_readonly;
GRANT SELECT ON education.v_course_quizzes TO trading_app;
