-- Unified Question System Migration
-- Replaces: practice_questions, assessment_questions, assessment_question_options, assessment_short_answers

-- 1. Create unified questions table
CREATE TABLE IF NOT EXISTS questions (
    id BIGSERIAL PRIMARY KEY,
    question_text TEXT NOT NULL,
    question_type VARCHAR(20) NOT NULL CHECK (question_type IN ('MCQ', 'TRUE_FALSE', 'SHORT_ANSWER')),
    difficulty_level VARCHAR(20) CHECK (difficulty_level IN ('EASY', 'MEDIUM', 'HARD')),
    points INT NOT NULL DEFAULT 1,
    explanation TEXT,
    tips TEXT,
    voice_prompt TEXT,
    sample_answer_voice_prompt TEXT,
    status VARCHAR(20) NOT NULL DEFAULT 'DRAFT' CHECK (status IN ('DRAFT', 'PUBLISHED', 'INACTIVE', 'ARCHIVED')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ
);

CREATE INDEX idx_questions_type ON questions(question_type);
CREATE INDEX idx_questions_status ON questions(status);
CREATE INDEX idx_questions_difficulty ON questions(difficulty_level);

-- 2. Create question options table (for MCQ and TRUE_FALSE)
CREATE TABLE IF NOT EXISTS question_options (
    id BIGSERIAL PRIMARY KEY,
    question_id BIGINT NOT NULL REFERENCES questions(id) ON DELETE CASCADE,
    option_text TEXT NOT NULL,
    option_order INT NOT NULL DEFAULT 0,
    is_correct BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_question_options_question_id ON question_options(question_id);

-- 3. Create question short answers table (for SHORT_ANSWER type)
CREATE TABLE IF NOT EXISTS question_short_answers (
    id BIGSERIAL PRIMARY KEY,
    question_id BIGINT NOT NULL REFERENCES questions(id) ON DELETE CASCADE,
    acceptable_answer TEXT NOT NULL,
    match_type VARCHAR(20) NOT NULL DEFAULT 'EXACT' CHECK (match_type IN ('EXACT', 'CONTAINS', 'CASE_INSENSITIVE')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_question_short_answers_question_id ON question_short_answers(question_id);

-- 4. Create question sets table (replaces practices for grouping questions)
CREATE TABLE IF NOT EXISTS question_sets (
    id BIGSERIAL PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    set_type VARCHAR(30) NOT NULL CHECK (set_type IN ('PRACTICE', 'INITIAL_ASSESSMENT', 'QUIZ', 'EXAM', 'SURVEY')),
    owner_type VARCHAR(30), -- SUB_COURSE, COURSE, CATEGORY, STANDALONE
    owner_id BIGINT, -- References the owning entity
    banner_image TEXT,
    persona VARCHAR(100),
    time_limit_minutes INT, -- Optional time limit
    passing_score INT, -- Optional passing percentage
    shuffle_questions BOOLEAN NOT NULL DEFAULT FALSE,
    status VARCHAR(20) NOT NULL DEFAULT 'DRAFT' CHECK (status IN ('DRAFT', 'PUBLISHED', 'INACTIVE', 'ARCHIVED')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ
);

CREATE INDEX idx_question_sets_type ON question_sets(set_type);
CREATE INDEX idx_question_sets_owner ON question_sets(owner_type, owner_id);
CREATE INDEX idx_question_sets_status ON question_sets(status);

-- 5. Create question set items table (links questions to sets)
CREATE TABLE IF NOT EXISTS question_set_items (
    id BIGSERIAL PRIMARY KEY,
    set_id BIGINT NOT NULL REFERENCES question_sets(id) ON DELETE CASCADE,
    question_id BIGINT NOT NULL REFERENCES questions(id) ON DELETE CASCADE,
    display_order INT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(set_id, question_id)
);

CREATE INDEX idx_question_set_items_set_id ON question_set_items(set_id);
CREATE INDEX idx_question_set_items_question_id ON question_set_items(question_id);

-- 6. Migrate data from assessment_questions to new questions table
INSERT INTO questions (id, question_text, question_type, difficulty_level, points, status, created_at)
SELECT 
    id,
    title,
    CASE question_type
        WHEN 'MULTIPLE_CHOICE' THEN 'MCQ'
        WHEN 'SHORT_ANSWER' THEN 'SHORT_ANSWER'
        WHEN 'TRUE_FALSE' THEN 'TRUE_FALSE'
        ELSE 'MCQ'
    END,
    CASE difficulty_level
        WHEN 'EASY' THEN 'EASY'
        WHEN 'MEDIUM' THEN 'MEDIUM'
        WHEN 'HARD' THEN 'HARD'
        ELSE 'MEDIUM'
    END,
    points,
    CASE WHEN is_active THEN 'PUBLISHED' ELSE 'INACTIVE' END,
    created_at
FROM assessment_questions;

-- 7. Migrate assessment_question_options to question_options
INSERT INTO question_options (question_id, option_text, option_order, is_correct, created_at)
SELECT question_id, option_text, option_order, is_correct, created_at
FROM assessment_question_options;

-- 8. Migrate assessment_short_answers to question_short_answers
INSERT INTO question_short_answers (question_id, acceptable_answer, match_type, created_at)
SELECT question_id, correct_answer, 'EXACT', created_at
FROM assessment_short_answers;

-- 9. Create initial assessment question set from existing data
INSERT INTO question_sets (title, description, set_type, owner_type, status, created_at)
VALUES ('Initial Assessment', 'Default initial assessment for new users', 'INITIAL_ASSESSMENT', 'STANDALONE', 'PUBLISHED', CURRENT_TIMESTAMP);

-- Link existing assessment questions to the initial assessment set
INSERT INTO question_set_items (set_id, question_id, display_order)
SELECT 
    (SELECT id FROM question_sets WHERE set_type = 'INITIAL_ASSESSMENT' LIMIT 1),
    id,
    id -- Use ID as initial display order
FROM questions
WHERE id IN (SELECT id FROM assessment_questions);

-- 10. Migrate practice_questions to new structure
-- First, get max ID from questions to avoid conflicts
DO $$
DECLARE
    max_q_id BIGINT;
    practice_rec RECORD;
    new_set_id BIGINT;
    new_question_id BIGINT;
BEGIN
    SELECT COALESCE(MAX(id), 0) INTO max_q_id FROM questions;
    
    -- For each practice in the old system, create a question_set
    FOR practice_rec IN 
        SELECT DISTINCT p.id, p.sub_course_id, p.title, p.description, p.banner_image, p.persona, p.status
        FROM practices p
    LOOP
        -- Create question set for this practice
        INSERT INTO question_sets (title, description, set_type, owner_type, owner_id, banner_image, persona, status, created_at)
        VALUES (
            practice_rec.title,
            practice_rec.description,
            'PRACTICE',
            'SUB_COURSE',
            practice_rec.sub_course_id,
            practice_rec.banner_image,
            practice_rec.persona,
            practice_rec.status,
            CURRENT_TIMESTAMP
        )
        RETURNING id INTO new_set_id;
        
        -- Migrate questions from this practice
        FOR new_question_id IN
            INSERT INTO questions (question_text, question_type, tips, sample_answer_voice_prompt, voice_prompt, status, created_at)
            SELECT 
                pq.question,
                pq.type,
                pq.tips,
                pq.sample_answer_voice_prompt,
                pq.question_voice_prompt,
                'PUBLISHED',
                CURRENT_TIMESTAMP
            FROM practice_questions pq
            WHERE pq.practice_id = practice_rec.id
            RETURNING id
        LOOP
            -- Link question to set
            INSERT INTO question_set_items (set_id, question_id, display_order)
            VALUES (new_set_id, new_question_id, new_question_id);
        END LOOP;
    END LOOP;
END $$;

-- 11. Reset sequences
SELECT setval(pg_get_serial_sequence('questions', 'id'), COALESCE((SELECT MAX(id) FROM questions), 1), true);
SELECT setval(pg_get_serial_sequence('question_options', 'id'), COALESCE((SELECT MAX(id) FROM question_options), 1), true);
SELECT setval(pg_get_serial_sequence('question_short_answers', 'id'), COALESCE((SELECT MAX(id) FROM question_short_answers), 1), true);
SELECT setval(pg_get_serial_sequence('question_sets', 'id'), COALESCE((SELECT MAX(id) FROM question_sets), 1), true);
SELECT setval(pg_get_serial_sequence('question_set_items', 'id'), COALESCE((SELECT MAX(id) FROM question_set_items), 1), true);

-- 12. Drop old tables
DROP TABLE IF EXISTS practice_questions CASCADE;
DROP TABLE IF EXISTS practices CASCADE;
DROP TABLE IF EXISTS assessment_attempt_answers CASCADE;
DROP TABLE IF EXISTS assessment_attempt_questions CASCADE;
DROP TABLE IF EXISTS assessment_attempts CASCADE;
DROP TABLE IF EXISTS assessment_short_answers CASCADE;
DROP TABLE IF EXISTS assessment_question_options CASCADE;
DROP TABLE IF EXISTS assessment_questions CASCADE;
