-- ============================================================================
-- SCHEMA: education
-- TABLE: modules
-- DESCRIPTION: Modulos/secciones de un curso
-- VERSION: 1.0.0
-- CREATED: 2026-01-16
-- SPRINT: Sprint 2 - DDL Implementation Roadmap Q1-2026
-- ============================================================================

-- Tabla de Modulos
CREATE TABLE IF NOT EXISTS education.modules (
    -- Identificadores
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    course_id UUID NOT NULL REFERENCES education.courses(id) ON DELETE CASCADE,
    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,

    -- Orden y estructura
    sequence_number INTEGER NOT NULL DEFAULT 0,

    -- Estado
    status education.publish_status NOT NULL DEFAULT 'draft',
    is_preview BOOLEAN NOT NULL DEFAULT FALSE,      -- Disponible como preview gratuito
    is_locked BOOLEAN NOT NULL DEFAULT FALSE,       -- Bloqueado hasta cumplir requisitos

    -- Requisitos para desbloquear
    unlock_requirements JSONB DEFAULT '{}'::JSONB,  -- { "modules": [], "min_score": 70 }

    -- Duracion
    estimated_duration_minutes INTEGER,

    -- Estadisticas (cache)
    lesson_count INTEGER NOT NULL DEFAULT 0,
    quiz_count INTEGER NOT NULL DEFAULT 0,

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

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

    -- Constraints
    CONSTRAINT modules_unique_sequence UNIQUE (course_id, sequence_number),
    CONSTRAINT modules_unique_slug UNIQUE (course_id, slug)
);

COMMENT ON TABLE education.modules IS
'Modulos o secciones que organizan las lecciones de un curso';

COMMENT ON COLUMN education.modules.is_preview IS
'Si TRUE, el modulo esta disponible como preview gratuito';

-- Indices
CREATE INDEX IF NOT EXISTS idx_modules_course
    ON education.modules(course_id, sequence_number);

CREATE INDEX IF NOT EXISTS idx_modules_tenant
    ON education.modules(tenant_id);

CREATE INDEX IF NOT EXISTS idx_modules_status
    ON education.modules(status);

CREATE INDEX IF NOT EXISTS idx_modules_preview
    ON education.modules(course_id, is_preview)
    WHERE is_preview = TRUE;

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

-- Trigger para actualizar conteo en curso
CREATE OR REPLACE FUNCTION education.update_course_module_count()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        UPDATE education.courses
        SET total_modules = total_modules + 1,
            last_content_update = NOW()
        WHERE id = NEW.course_id;
    ELSIF TG_OP = 'DELETE' THEN
        UPDATE education.courses
        SET total_modules = total_modules - 1,
            last_content_update = NOW()
        WHERE id = OLD.course_id;
    END IF;

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

DROP TRIGGER IF EXISTS module_course_count ON education.modules;
CREATE TRIGGER module_course_count
    AFTER INSERT OR DELETE ON education.modules
    FOR EACH ROW
    EXECUTE FUNCTION education.update_course_module_count();

-- Vista de modulos con lecciones
CREATE OR REPLACE VIEW education.v_course_modules AS
SELECT
    m.id,
    m.course_id,
    m.title,
    m.slug,
    m.description,
    m.sequence_number,
    m.status,
    m.is_preview,
    m.is_locked,
    m.estimated_duration_minutes,
    m.lesson_count,
    m.quiz_count
FROM education.modules m
WHERE m.status = 'published'
ORDER BY m.course_id, m.sequence_number;

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

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

-- Grants
GRANT SELECT, INSERT, UPDATE, DELETE ON education.modules TO trading_app;
GRANT SELECT ON education.modules TO trading_readonly;
GRANT SELECT ON education.v_course_modules TO trading_app;
