-- Sequential order for programs, courses, modules, and lessons (1 = first in each scope).
-- Progress tables mark completion; API enforces prerequisites for learners (STUDENT role).

ALTER TABLE programs
    ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
ALTER TABLE courses
    ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
ALTER TABLE modules
    ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
ALTER TABLE lessons
    ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;

-- Program order (one global sequence): Beginner -> Intermediate -> Advanced; others by id
UPDATE programs
SET sort_order = v.so
FROM (
    VALUES
        ('Beginner', 1),
        ('Intermediate', 2),
        ('Advanced', 3)
) AS v (name, so)
WHERE programs.name = v.name;

UPDATE programs
SET sort_order = 1000 + r.rn
FROM (
    SELECT
        id,
        row_number() OVER (
            ORDER BY id
        ) AS rn
    FROM programs
    WHERE
        sort_order = 0
) AS r
WHERE
    programs.id = r.id;

-- CEFR courses: A1..C2; remaining courses in each program: stable order
UPDATE courses
SET sort_order = CASE name
    WHEN 'A1' THEN
        1
    WHEN 'A2' THEN
        2
    WHEN 'B1' THEN
        3
    WHEN 'B2' THEN
        4
    WHEN 'C1' THEN
        5
    WHEN 'C2' THEN
        6
    ELSE
        0
END
WHERE
    name IN ('A1', 'A2', 'B1', 'B2', 'C1', 'C2');

UPDATE courses c
SET sort_order = 2000 + s.rn
FROM (
    SELECT
        id,
        row_number() OVER (
            PARTITION BY program_id
            ORDER BY
                id
        ) AS rn
    FROM courses
    WHERE
        sort_order = 0
) AS s
WHERE
    c.id = s.id;

UPDATE modules m
SET sort_order = r.rn
FROM (
    SELECT
        id,
        row_number() OVER (
            PARTITION BY course_id
            ORDER BY
                id
        ) AS rn
    FROM modules
) AS r
WHERE
    m.id = r.id;

UPDATE lessons l
SET sort_order = r.rn
FROM (
    SELECT
        id,
        row_number() OVER (
            PARTITION BY module_id
            ORDER BY
                id
        ) AS rn
    FROM lessons
) AS r
WHERE
    l.id = r.id;

CREATE UNIQUE INDEX uq_programs_sort_order ON programs (sort_order);
CREATE UNIQUE INDEX uq_courses_program_sort ON courses (program_id, sort_order);
CREATE UNIQUE INDEX uq_modules_course_sort ON modules (course_id, sort_order);
CREATE UNIQUE INDEX uq_lessons_module_sort ON lessons (module_id, sort_order);

CREATE TABLE lms_user_lesson_progress (
    user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
    lesson_id BIGINT NOT NULL REFERENCES lessons (id) ON DELETE CASCADE,
    completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id, lesson_id)
);

CREATE INDEX idx_lms_user_lesson_progress_user ON lms_user_lesson_progress (user_id);
CREATE INDEX idx_lms_user_lesson_progress_lesson ON lms_user_lesson_progress (lesson_id);

CREATE TABLE lms_user_module_progress (
    user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
    module_id BIGINT NOT NULL REFERENCES modules (id) ON DELETE CASCADE,
    completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id, module_id)
);

CREATE INDEX idx_lms_user_module_progress_user ON lms_user_module_progress (user_id);
CREATE INDEX idx_lms_user_module_progress_module ON lms_user_module_progress (module_id);

CREATE TABLE lms_user_course_progress (
    user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
    course_id BIGINT NOT NULL REFERENCES courses (id) ON DELETE CASCADE,
    completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id, course_id)
);

CREATE INDEX idx_lms_user_course_progress_user ON lms_user_course_progress (user_id);
CREATE INDEX idx_lms_user_course_progress_course ON lms_user_course_progress (course_id);

CREATE TABLE lms_user_program_progress (
    user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
    program_id BIGINT NOT NULL REFERENCES programs (id) ON DELETE CASCADE,
    completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id, program_id)
);

CREATE INDEX idx_lms_user_program_progress_user ON lms_user_program_progress (user_id);
CREATE INDEX idx_lms_user_program_progress_program ON lms_user_program_progress (program_id);
