-- ============================================================================
-- SCHEMA: education
-- TABLE: lessons
-- DESCRIPTION: Lecciones individuales de un modulo
-- VERSION: 1.0.0
-- CREATED: 2026-01-16
-- SPRINT: Sprint 2 - DDL Implementation Roadmap Q1-2026
-- ============================================================================

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

    -- Tipo de contenido
    content_type education.content_type NOT NULL DEFAULT 'video',

    -- Orden
    sequence_number INTEGER NOT NULL DEFAULT 0,

    -- Contenido principal
    content TEXT,                                   -- Contenido HTML/Markdown
    content_json JSONB,                             -- Contenido estructurado

    -- Video
    video_url TEXT,
    video_provider VARCHAR(50),                     -- 'youtube', 'vimeo', 'bunny', 'self'
    video_id VARCHAR(100),
    video_duration_seconds INTEGER,
    video_thumbnail_url TEXT,

    -- Recursos
    resources JSONB DEFAULT '[]'::JSONB,           -- Array de archivos descargables
    -- [{ "name": "PDF", "url": "...", "type": "pdf", "size": 1024 }]

    -- Interactividad
    has_quiz BOOLEAN NOT NULL DEFAULT FALSE,
    quiz_id UUID,                                   -- Quiz asociado a esta leccion

    -- Estado
    status education.publish_status NOT NULL DEFAULT 'draft',
    is_preview BOOLEAN NOT NULL DEFAULT FALSE,
    is_mandatory BOOLEAN NOT NULL DEFAULT TRUE,    -- Obligatoria para completar curso

    -- Duracion
    estimated_duration_minutes INTEGER,

    -- Requisitos
    requires_previous_completion BOOLEAN NOT NULL DEFAULT FALSE,

    -- Gamificacion
    xp_reward INTEGER DEFAULT 10,

    -- AI Generated content
    is_ai_generated BOOLEAN NOT NULL DEFAULT FALSE,
    ai_generation_prompt TEXT,

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

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

    -- Constraints
    CONSTRAINT lessons_unique_sequence UNIQUE (module_id, sequence_number),
    CONSTRAINT lessons_unique_slug UNIQUE (module_id, slug)
);

COMMENT ON TABLE education.lessons IS
'Lecciones individuales que componen un modulo del curso';

COMMENT ON COLUMN education.lessons.content_type IS
'Tipo de contenido: video, article, quiz, interactive, download, live, assignment';

-- Indices
CREATE INDEX IF NOT EXISTS idx_lessons_module
    ON education.lessons(module_id, sequence_number);

CREATE INDEX IF NOT EXISTS idx_lessons_course
    ON education.lessons(course_id);

CREATE INDEX IF NOT EXISTS idx_lessons_tenant
    ON education.lessons(tenant_id);

CREATE INDEX IF NOT EXISTS idx_lessons_status
    ON education.lessons(status);

CREATE INDEX IF NOT EXISTS idx_lessons_content_type
    ON education.lessons(content_type);

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

CREATE INDEX IF NOT EXISTS idx_lessons_with_quiz
    ON education.lessons(quiz_id)
    WHERE quiz_id IS NOT NULL;

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

-- Trigger para actualizar conteos
CREATE OR REPLACE FUNCTION education.update_lesson_counts()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        -- Actualizar modulo
        UPDATE education.modules
        SET lesson_count = lesson_count + 1
        WHERE id = NEW.module_id;

        -- Actualizar curso
        UPDATE education.courses
        SET total_lessons = total_lessons + 1,
            last_content_update = NOW()
        WHERE id = NEW.course_id;

    ELSIF TG_OP = 'DELETE' THEN
        UPDATE education.modules
        SET lesson_count = lesson_count - 1
        WHERE id = OLD.module_id;

        UPDATE education.courses
        SET total_lessons = total_lessons - 1,
            last_content_update = NOW()
        WHERE id = OLD.course_id;
    END IF;

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

DROP TRIGGER IF EXISTS lesson_counts ON education.lessons;
CREATE TRIGGER lesson_counts
    AFTER INSERT OR DELETE ON education.lessons
    FOR EACH ROW
    EXECUTE FUNCTION education.update_lesson_counts();

-- Vista de lecciones de un curso
CREATE OR REPLACE VIEW education.v_course_lessons AS
SELECT
    l.id,
    l.module_id,
    l.course_id,
    m.title AS module_title,
    m.sequence_number AS module_sequence,
    l.title,
    l.slug,
    l.content_type,
    l.sequence_number,
    l.video_duration_seconds,
    l.estimated_duration_minutes,
    l.is_preview,
    l.is_mandatory,
    l.has_quiz,
    l.status
FROM education.lessons l
JOIN education.modules m ON l.module_id = m.id
WHERE l.status = 'published'
ORDER BY m.sequence_number, l.sequence_number;

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

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

-- Grants
GRANT SELECT, INSERT, UPDATE, DELETE ON education.lessons TO trading_app;
GRANT SELECT ON education.lessons TO trading_readonly;
GRANT SELECT ON education.v_course_lessons TO trading_app;
