-- Unified hierarchy
-- Course Category -> Course Sub-category -> Course -> Level -> Module -> Sub-Module
--                                                          -> Sub-Module Videos
--                                                          -> Sub-Module Practices (question sets)

CREATE TABLE IF NOT EXISTS course_sub_categories (
    id BIGSERIAL PRIMARY KEY,
    category_id BIGINT NOT NULL REFERENCES course_categories(id) ON DELETE CASCADE,
    name VARCHAR(150) NOT NULL,
    description TEXT,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    display_order INT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(category_id, name)
);

ALTER TABLE courses
ADD COLUMN IF NOT EXISTS sub_category_id BIGINT REFERENCES course_sub_categories(id) ON DELETE SET NULL;

CREATE INDEX IF NOT EXISTS idx_courses_sub_category_id ON courses(sub_category_id);

CREATE TABLE IF NOT EXISTS levels (
    id BIGSERIAL PRIMARY KEY,
    course_id BIGINT NOT NULL REFERENCES courses(id) ON DELETE CASCADE,
    cefr_level VARCHAR(2) NOT NULL,
    display_order INT NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(course_id, cefr_level),
    CHECK (cefr_level IN ('A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3'))
);

CREATE INDEX IF NOT EXISTS idx_levels_course_id ON levels(course_id);

CREATE TABLE IF NOT EXISTS modules (
    id BIGSERIAL PRIMARY KEY,
    level_id BIGINT NOT NULL REFERENCES levels(id) ON DELETE CASCADE,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    display_order INT NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_modules_level_id ON modules(level_id);

CREATE TABLE IF NOT EXISTS sub_modules (
    id BIGSERIAL PRIMARY KEY,
    module_id BIGINT NOT NULL REFERENCES modules(id) ON DELETE CASCADE,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    display_order INT NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    legacy_sub_course_id BIGINT UNIQUE
);

CREATE INDEX IF NOT EXISTS idx_sub_modules_module_id ON sub_modules(module_id);

CREATE TABLE IF NOT EXISTS sub_module_videos (
    id BIGSERIAL PRIMARY KEY,
    sub_module_id BIGINT NOT NULL REFERENCES sub_modules(id) ON DELETE CASCADE,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    video_url TEXT NOT NULL,
    duration INT,
    resolution VARCHAR(20),
    is_published BOOLEAN NOT NULL DEFAULT FALSE,
    publish_date TIMESTAMPTZ,
    visibility VARCHAR(50),
    instructor_id VARCHAR(100),
    thumbnail TEXT,
    display_order INT NOT NULL DEFAULT 0,
    status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
    vimeo_id TEXT,
    vimeo_embed_url TEXT,
    vimeo_player_html TEXT,
    vimeo_status VARCHAR(50),
    video_host_provider VARCHAR(20),
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_sub_module_videos_sub_module_id ON sub_module_videos(sub_module_id);

CREATE TABLE IF NOT EXISTS sub_module_practices (
    id BIGSERIAL PRIMARY KEY,
    sub_module_id BIGINT NOT NULL REFERENCES sub_modules(id) ON DELETE CASCADE,
    question_set_id BIGINT NOT NULL REFERENCES question_sets(id) ON DELETE CASCADE,
    intro_video_url TEXT,
    display_order INT NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(question_set_id)
);

CREATE INDEX IF NOT EXISTS idx_sub_module_practices_sub_module_id ON sub_module_practices(sub_module_id);

-- Practice progress now supports sub-module owned practices where no legacy sub_course exists.
ALTER TABLE user_practice_progress
ALTER COLUMN sub_course_id DROP NOT NULL;

-- Backfill from existing structure
INSERT INTO course_sub_categories (category_id, name, description, display_order, is_active)
SELECT cc.id, c.title || ' Group', 'Auto-generated from existing course structure', 0, TRUE
FROM courses c
JOIN course_categories cc ON cc.id = c.category_id
LEFT JOIN course_sub_categories csc
  ON csc.category_id = cc.id AND csc.name = c.title || ' Group'
WHERE csc.id IS NULL;

UPDATE courses c
SET sub_category_id = csc.id
FROM course_sub_categories csc
WHERE csc.category_id = c.category_id
  AND csc.name = c.title || ' Group'
  AND c.sub_category_id IS NULL;

INSERT INTO levels (course_id, cefr_level, display_order, is_active)
SELECT
    sc.course_id,
    sc.sub_level,
    MIN(sc.display_order),
    BOOL_AND(sc.is_active)
FROM sub_courses sc
WHERE sc.sub_level IN ('A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3')
GROUP BY sc.course_id, sc.sub_level
ON CONFLICT (course_id, cefr_level) DO NOTHING;

INSERT INTO modules (level_id, title, description, display_order, is_active)
SELECT
    l.id,
    l.cefr_level || ' Module 1',
    'Auto-generated default module for ' || l.cefr_level,
    1,
    l.is_active
FROM levels l
LEFT JOIN modules m ON m.level_id = l.id AND m.display_order = 1
WHERE m.id IS NULL;

INSERT INTO sub_modules (module_id, title, description, display_order, is_active, legacy_sub_course_id)
SELECT
    m.id,
    sc.title,
    sc.description,
    sc.display_order,
    sc.is_active,
    sc.id
FROM sub_courses sc
JOIN levels l
  ON l.course_id = sc.course_id
 AND l.cefr_level = sc.sub_level
JOIN modules m
  ON m.level_id = l.id
 AND m.display_order = 1
LEFT JOIN sub_modules sm ON sm.legacy_sub_course_id = sc.id
WHERE sm.id IS NULL;

INSERT INTO sub_module_videos (
    sub_module_id,
    title,
    description,
    video_url,
    duration,
    resolution,
    is_published,
    publish_date,
    visibility,
    instructor_id,
    thumbnail,
    display_order,
    status,
    vimeo_id,
    vimeo_embed_url,
    vimeo_player_html,
    vimeo_status,
    video_host_provider
)
SELECT
    sm.id,
    scv.title,
    scv.description,
    scv.video_url,
    scv.duration,
    scv.resolution,
    scv.is_published,
    scv.publish_date,
    scv.visibility,
    scv.instructor_id,
    scv.thumbnail,
    scv.display_order,
    scv.status,
    scv.vimeo_id,
    scv.vimeo_embed_url,
    scv.vimeo_player_html,
    scv.vimeo_status,
    scv.video_host_provider
FROM sub_course_videos scv
JOIN sub_modules sm ON sm.legacy_sub_course_id = scv.sub_course_id
WHERE NOT EXISTS (
    SELECT 1
    FROM sub_module_videos smv
    WHERE smv.sub_module_id = sm.id
      AND smv.title = scv.title
      AND COALESCE(smv.video_url, '') = COALESCE(scv.video_url, '')
);

UPDATE question_sets qs
SET owner_type = 'SUB_MODULE',
    owner_id = sm.id
FROM sub_modules sm
WHERE qs.owner_type = 'SUB_COURSE'
  AND qs.owner_id = sm.legacy_sub_course_id
  AND qs.set_type = 'PRACTICE';

INSERT INTO sub_module_practices (sub_module_id, question_set_id, intro_video_url, display_order, is_active)
SELECT
    sm.id,
    qs.id,
    qs.intro_video_url,
    COALESCE(qs.display_order, 0),
    (qs.status != 'ARCHIVED')
FROM question_sets qs
JOIN sub_modules sm
  ON qs.owner_type = 'SUB_MODULE'
 AND qs.owner_id = sm.id
WHERE qs.set_type = 'PRACTICE'
ON CONFLICT (question_set_id) DO NOTHING;

