-- Add sub-level support to sub_courses and enforce valid level/sub-level combinations.
ALTER TABLE sub_courses
ADD COLUMN sub_level VARCHAR(2);

UPDATE sub_courses
SET sub_level = CASE level
    WHEN 'BEGINNER' THEN 'A1'
    WHEN 'INTERMEDIATE' THEN 'B1'
    WHEN 'ADVANCED' THEN 'C1'
    ELSE 'A1'
END
WHERE sub_level IS NULL;

ALTER TABLE sub_courses
ALTER COLUMN sub_level SET NOT NULL;

ALTER TABLE sub_courses
ADD CONSTRAINT sub_courses_level_sub_level_check CHECK (
    (level = 'BEGINNER' AND sub_level IN ('A1', 'A2', 'A3')) OR
    (level = 'INTERMEDIATE' AND sub_level IN ('B1', 'B2', 'B3')) OR
    (level = 'ADVANCED' AND sub_level IN ('C1', 'C2', 'C3'))
);

CREATE INDEX idx_sub_courses_level_sub_level ON sub_courses(level, sub_level);

-- Ensure each sub-course has an entry-assessment question set.
CREATE UNIQUE INDEX idx_question_sets_unique_subcourse_initial_assessment
ON question_sets(owner_type, owner_id, set_type)
WHERE owner_type = 'SUB_COURSE' AND set_type = 'INITIAL_ASSESSMENT' AND status != 'ARCHIVED';

CREATE OR REPLACE FUNCTION clone_default_initial_assessment_items(target_set_id BIGINT)
RETURNS VOID AS $$
DECLARE
    template_set_id BIGINT;
BEGIN
    SELECT id
    INTO template_set_id
    FROM question_sets
    WHERE set_type = 'INITIAL_ASSESSMENT'
      AND owner_type = 'STANDALONE'
      AND status = 'PUBLISHED'
    ORDER BY created_at DESC
    LIMIT 1;

    IF template_set_id IS NULL THEN
        RETURN;
    END IF;

    INSERT INTO question_set_items (set_id, question_id, display_order)
    SELECT target_set_id, qsi.question_id, qsi.display_order
    FROM question_set_items qsi
    WHERE qsi.set_id = template_set_id
      AND NOT EXISTS (
          SELECT 1
          FROM question_set_items existing
          WHERE existing.set_id = target_set_id
            AND existing.question_id = qsi.question_id
      );
END;
$$ LANGUAGE plpgsql;

INSERT INTO question_sets (
    title,
    description,
    set_type,
    owner_type,
    owner_id,
    shuffle_questions,
    status
)
SELECT
    sc.title || ' Entry Assessment',
    'Entry assessment used to evaluate learners before joining this sub-course.',
    'INITIAL_ASSESSMENT',
    'SUB_COURSE',
    sc.id,
    false,
    'DRAFT'
FROM sub_courses sc
WHERE NOT EXISTS (
    SELECT 1
    FROM question_sets qs
    WHERE qs.owner_type = 'SUB_COURSE'
      AND qs.owner_id = sc.id
      AND qs.set_type = 'INITIAL_ASSESSMENT'
      AND qs.status != 'ARCHIVED'
);

DO $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN
        SELECT id
        FROM question_sets
        WHERE owner_type = 'SUB_COURSE'
          AND set_type = 'INITIAL_ASSESSMENT'
          AND status != 'ARCHIVED'
    LOOP
        IF NOT EXISTS (SELECT 1 FROM question_set_items WHERE set_id = r.id) THEN
            PERFORM clone_default_initial_assessment_items(r.id);
        END IF;
    END LOOP;
END;
$$;

CREATE OR REPLACE FUNCTION create_sub_course_entry_assessment()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO question_sets (
        title,
        description,
        set_type,
        owner_type,
        owner_id,
        shuffle_questions,
        status
    )
    VALUES (
        NEW.title || ' Entry Assessment',
        'Entry assessment used to evaluate learners before joining this sub-course.',
        'INITIAL_ASSESSMENT',
        'SUB_COURSE',
        NEW.id,
        false,
        'DRAFT'
    )
    ON CONFLICT DO NOTHING;

    PERFORM clone_default_initial_assessment_items((
        SELECT id
        FROM question_sets
        WHERE owner_type = 'SUB_COURSE'
          AND owner_id = NEW.id
          AND set_type = 'INITIAL_ASSESSMENT'
          AND status != 'ARCHIVED'
        ORDER BY created_at DESC
        LIMIT 1
    ));

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_sub_courses_create_entry_assessment
AFTER INSERT ON sub_courses
FOR EACH ROW
EXECUTE FUNCTION create_sub_course_entry_assessment();
