use rusqlite::Connection;

/// Current schema version - must match the TypeScript schemaVersion
const SCHEMA_VERSION: u32 = 3;

/// Initialize the local SQLite database with all required tables.
/// This creates the full schema from scratch (for new databases).
pub fn initialize_schema(conn: &Connection) -> Result<(), rusqlite::Error> {
    // Enable foreign keys
    conn.execute_batch("PRAGMA foreign_keys = ON;")?;

    conn.execute_batch(
        "
        -- =========================================================================
        -- AI TABLES
        -- =========================================================================

        -- AI Conversations
        CREATE TABLE IF NOT EXISTS ai_conversations (
            conversation_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            mode TEXT NOT NULL,
            title TEXT NOT NULL,
            start_date INTEGER NOT NULL,
            status INTEGER NOT NULL,
            user_id TEXT NOT NULL,
            summary TEXT,
            convo_meta TEXT NOT NULL,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- AI Messages History
        CREATE TABLE IF NOT EXISTS ai_messages_history (
            message_id TEXT PRIMARY KEY,
            conversation_id TEXT NOT NULL,
            role TEXT NOT NULL,
            message TEXT NOT NULL,
            message_date INTEGER NOT NULL,
            FOREIGN KEY (conversation_id) REFERENCES ai_conversations(conversation_id) ON DELETE CASCADE
        );

        -- =========================================================================
        -- BOOK TABLES
        -- =========================================================================

        -- Book Acts
        CREATE TABLE IF NOT EXISTS book_acts (
            act_id INTEGER PRIMARY KEY,
            title TEXT NOT NULL,
            last_update INTEGER DEFAULT 0
        );

        -- Book Act Summaries
        CREATE TABLE IF NOT EXISTS book_act_summaries (
            act_sum_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            act_index INTEGER NOT NULL,
            summary TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book AI Guide Line
        CREATE TABLE IF NOT EXISTS book_ai_guide_line (
            user_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            global_resume TEXT,
            themes TEXT,
            verbe_tense INTEGER,
            narrative_type INTEGER,
            langue INTEGER,
            dialogue_type INTEGER,
            tone TEXT,
            atmosphere TEXT,
            current_resume TEXT,
            last_update INTEGER DEFAULT 0,
            PRIMARY KEY (user_id, book_id),
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Chapters
        CREATE TABLE IF NOT EXISTS book_chapters (
            chapter_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            author_id TEXT NOT NULL,
            title TEXT NOT NULL,
            hashed_title TEXT,
            words_count INTEGER,
            chapter_order INTEGER,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Chapter Content
        CREATE TABLE IF NOT EXISTS book_chapter_content (
            content_id TEXT PRIMARY KEY,
            chapter_id TEXT NOT NULL,
            author_id TEXT NOT NULL,
            version INTEGER NOT NULL DEFAULT 2,
            content TEXT,
            words_count INTEGER NOT NULL,
            time_on_it INTEGER NOT NULL DEFAULT 0,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (chapter_id) REFERENCES book_chapters(chapter_id) ON DELETE CASCADE
        );

        -- Book Chapter Infos
        CREATE TABLE IF NOT EXISTS book_chapter_infos (
            chapter_info_id TEXT PRIMARY KEY,
            chapter_id TEXT,
            act_id INTEGER,
            incident_id TEXT,
            plot_point_id TEXT,
            book_id TEXT,
            author_id TEXT,
            summary TEXT,
            goal TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (chapter_id) REFERENCES book_chapters(chapter_id) ON DELETE CASCADE,
            FOREIGN KEY (incident_id) REFERENCES book_incidents(incident_id) ON DELETE CASCADE,
            FOREIGN KEY (plot_point_id) REFERENCES book_plot_points(plot_point_id) ON DELETE CASCADE
        );

        -- Book Characters
        CREATE TABLE IF NOT EXISTS book_characters (
            character_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            first_name TEXT NOT NULL,
            last_name TEXT,
            nickname TEXT,
            age TEXT,
            gender TEXT,
            species TEXT,
            nationality TEXT,
            status TEXT,
            category TEXT NOT NULL,
            title TEXT,
            image TEXT,
            role TEXT,
            biography TEXT,
            history TEXT,
            speech_pattern TEXT,
            catchphrase TEXT,
            residence TEXT,
            notes TEXT,
            color TEXT,
            series_character_id TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE,
            FOREIGN KEY (series_character_id) REFERENCES series_characters(character_id) ON DELETE SET NULL
        );

        -- Book Character Attributes
        CREATE TABLE IF NOT EXISTS book_characters_attributes (
            attr_id TEXT PRIMARY KEY,
            character_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            attribute_name TEXT NOT NULL,
            attribute_value TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (character_id) REFERENCES book_characters(character_id) ON DELETE CASCADE
        );

        -- Book Character Relations
        CREATE TABLE IF NOT EXISTS book_characters_relations (
            rel_id INTEGER PRIMARY KEY,
            character_id INTEGER NOT NULL,
            char_name TEXT NOT NULL,
            type TEXT NOT NULL,
            description TEXT NOT NULL,
            history TEXT NOT NULL,
            last_update INTEGER DEFAULT 0
        );

        -- Book Guide Line
        CREATE TABLE IF NOT EXISTS book_guide_line (
            user_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            tone TEXT,
            atmosphere TEXT,
            writing_style TEXT,
            themes TEXT,
            symbolism TEXT,
            motifs TEXT,
            narrative_voice TEXT,
            pacing TEXT,
            intended_audience TEXT,
            key_messages TEXT,
            last_update INTEGER DEFAULT 0,
            PRIMARY KEY (user_id, book_id),
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Incidents
        CREATE TABLE IF NOT EXISTS book_incidents (
            incident_id TEXT PRIMARY KEY,
            author_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            title TEXT NOT NULL,
            hashed_title TEXT NOT NULL,
            summary TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Issues
        CREATE TABLE IF NOT EXISTS book_issues (
            issue_id TEXT PRIMARY KEY,
            author_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_issue_name TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Location
        CREATE TABLE IF NOT EXISTS book_location (
            loc_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            loc_name TEXT NOT NULL,
            loc_original_name TEXT NOT NULL,
            series_location_id TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE,
            FOREIGN KEY (series_location_id) REFERENCES series_locations(loc_id) ON DELETE SET NULL
        );

        -- Book Plot Points
        CREATE TABLE IF NOT EXISTS book_plot_points (
            plot_point_id TEXT PRIMARY KEY,
            title TEXT NOT NULL,
            hashed_title TEXT NOT NULL,
            summary TEXT,
            linked_incident_id TEXT,
            author_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book World
        CREATE TABLE IF NOT EXISTS book_world (
            world_id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            author_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            history TEXT,
            politics TEXT,
            economy TEXT,
            religion TEXT,
            languages TEXT,
            series_world_id TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE,
            FOREIGN KEY (series_world_id) REFERENCES series_worlds(world_id) ON DELETE SET NULL
        );

        -- Book World Elements
        CREATE TABLE IF NOT EXISTS book_world_elements (
            element_id TEXT PRIMARY KEY,
            world_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_type INTEGER NOT NULL,
            name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (world_id) REFERENCES book_world(world_id) ON DELETE CASCADE
        );

        -- =========================================================================
        -- CORE TABLES
        -- =========================================================================

        -- Erit Books
        CREATE TABLE IF NOT EXISTS erit_books (
            book_id TEXT PRIMARY KEY,
            type TEXT NOT NULL,
            author_id TEXT NOT NULL,
            title TEXT NOT NULL,
            hashed_title TEXT NOT NULL,
            sub_title TEXT,
            hashed_sub_title TEXT,
            summary TEXT,
            serie_id INTEGER,
            desired_release_date TEXT,
            desired_word_count INTEGER,
            words_count INTEGER,
            cover_image TEXT,
            last_update INTEGER DEFAULT 0
        );

        -- Erit Book Series (legacy)
        CREATE TABLE IF NOT EXISTS erit_book_series (
            serie_id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            author_id INTEGER NOT NULL
        );

        -- Erit Editor Settings
        CREATE TABLE IF NOT EXISTS erit_editor (
            user_id TEXT,
            type TEXT NOT NULL,
            text_size INTEGER NOT NULL,
            text_intent INTEGER NOT NULL,
            interline TEXT NOT NULL,
            paper_width INTEGER NOT NULL,
            theme TEXT NOT NULL,
            focus INTEGER NOT NULL
        );

        -- Erit Users
        CREATE TABLE IF NOT EXISTS erit_users (
            user_id TEXT PRIMARY KEY,
            username TEXT NOT NULL,
            email TEXT NOT NULL,
            origin_email TEXT NOT NULL,
            origin_username TEXT NOT NULL,
            author_name TEXT,
            origin_author_name TEXT,
            social_id TEXT,
            user_group INTEGER NOT NULL DEFAULT 4,
            password TEXT
        );

        -- =========================================================================
        -- LOCATION TABLES
        -- =========================================================================

        -- Location Element
        CREATE TABLE IF NOT EXISTS location_element (
            element_id TEXT PRIMARY KEY,
            location TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            element_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (location) REFERENCES book_location(loc_id) ON DELETE CASCADE
        );

        -- Location Sub Element
        CREATE TABLE IF NOT EXISTS location_sub_element (
            sub_element_id TEXT PRIMARY KEY,
            element_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            sub_elem_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            sub_elem_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (element_id) REFERENCES location_element(element_id) ON DELETE CASCADE
        );

        -- =========================================================================
        -- USER TABLES
        -- =========================================================================

        -- User Keys
        CREATE TABLE IF NOT EXISTS user_keys (
            user_id TEXT NOT NULL,
            brand TEXT NOT NULL,
            key TEXT NOT NULL,
            actif INTEGER NOT NULL DEFAULT 1,
            FOREIGN KEY (user_id) REFERENCES erit_users(user_id) ON DELETE CASCADE
        );

        -- User Last Chapter
        CREATE TABLE IF NOT EXISTS user_last_chapter (
            user_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            chapter_id TEXT NOT NULL,
            version INTEGER NOT NULL,
            PRIMARY KEY (user_id, book_id),
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE,
            FOREIGN KEY (chapter_id) REFERENCES book_chapters(chapter_id) ON DELETE CASCADE
        );

        -- =========================================================================
        -- BOOK TOOLS & SPELLS
        -- =========================================================================

        -- Book Tools
        CREATE TABLE IF NOT EXISTS book_tools (
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            characters_enabled INTEGER NOT NULL DEFAULT 0,
            worlds_enabled INTEGER NOT NULL DEFAULT 0,
            locations_enabled INTEGER NOT NULL DEFAULT 0,
            spells_enabled INTEGER NOT NULL DEFAULT 0,
            last_update INTEGER DEFAULT 0,
            UNIQUE (book_id, user_id),
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Spell Tags
        CREATE TABLE IF NOT EXISTS book_spell_tags (
            tag_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Book Spells
        CREATE TABLE IF NOT EXISTS book_spells (
            spell_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            description TEXT,
            appearance TEXT,
            tags TEXT,
            power_level TEXT,
            components TEXT,
            limitations TEXT,
            notes TEXT,
            series_spell_id TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE,
            FOREIGN KEY (series_spell_id) REFERENCES series_spells(spell_id) ON DELETE SET NULL
        );

        -- =========================================================================
        -- SERIES TABLES
        -- =========================================================================

        -- Book Series (main series table)
        CREATE TABLE IF NOT EXISTS book_series (
            series_id TEXT PRIMARY KEY,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            description TEXT,
            cover_image TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (user_id) REFERENCES erit_users(user_id) ON DELETE CASCADE
        );

        -- Series Books (link series to books with order)
        CREATE TABLE IF NOT EXISTS series_books (
            series_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            book_order INTEGER NOT NULL DEFAULT 1,
            last_update INTEGER DEFAULT 0,
            PRIMARY KEY (series_id, book_id),
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );

        -- Series Characters
        CREATE TABLE IF NOT EXISTS series_characters (
            character_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            first_name TEXT NOT NULL,
            last_name TEXT,
            nickname TEXT,
            age TEXT,
            gender TEXT,
            species TEXT,
            nationality TEXT,
            status TEXT,
            category TEXT NOT NULL,
            title TEXT,
            image TEXT,
            role TEXT,
            biography TEXT,
            history TEXT,
            speech_pattern TEXT,
            catchphrase TEXT,
            residence TEXT,
            notes TEXT,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );

        -- Series Characters Attributes
        CREATE TABLE IF NOT EXISTS series_characters_attributes (
            attr_id TEXT PRIMARY KEY,
            character_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            attribute_name TEXT NOT NULL,
            attribute_value TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (character_id) REFERENCES series_characters(character_id) ON DELETE CASCADE
        );

        -- Series Worlds
        CREATE TABLE IF NOT EXISTS series_worlds (
            world_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            history TEXT,
            politics TEXT,
            economy TEXT,
            religion TEXT,
            languages TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );

        -- Series World Elements
        CREATE TABLE IF NOT EXISTS series_world_elements (
            element_id TEXT PRIMARY KEY,
            world_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_type INTEGER NOT NULL,
            name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (world_id) REFERENCES series_worlds(world_id) ON DELETE CASCADE
        );

        -- Series Locations
        CREATE TABLE IF NOT EXISTS series_locations (
            loc_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            loc_name TEXT NOT NULL,
            loc_original_name TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );

        -- Series Location Elements
        CREATE TABLE IF NOT EXISTS series_location_elements (
            element_id TEXT PRIMARY KEY,
            location_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            element_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (location_id) REFERENCES series_locations(loc_id) ON DELETE CASCADE
        );

        -- Series Location Sub Elements
        CREATE TABLE IF NOT EXISTS series_location_sub_elements (
            sub_element_id TEXT PRIMARY KEY,
            element_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            sub_elem_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            sub_elem_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (element_id) REFERENCES series_location_elements(element_id) ON DELETE CASCADE
        );

        -- Series Spells
        CREATE TABLE IF NOT EXISTS series_spells (
            spell_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            description TEXT,
            appearance TEXT,
            tags TEXT,
            power_level TEXT,
            components TEXT,
            limitations TEXT,
            notes TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );

        -- Series Spell Tags
        CREATE TABLE IF NOT EXISTS series_spell_tags (
            tag_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );

        -- =========================================================================
        -- SYNC DELETION TRACKING
        -- =========================================================================

        -- Removed Items (sync deletion tracking)
        CREATE TABLE IF NOT EXISTS removed_items (
            removal_id TEXT PRIMARY KEY,
            table_name TEXT NOT NULL,
            entity_id TEXT NOT NULL,
            book_id TEXT,
            user_id TEXT NOT NULL,
            deleted_at INTEGER NOT NULL,
            removed_time INTEGER NOT NULL DEFAULT 0
        );

        -- =========================================================================
        -- INDEXES
        -- =========================================================================

        -- AI indexes
        CREATE INDEX IF NOT EXISTS idx_ai_conversations_book ON ai_conversations(book_id);
        CREATE INDEX IF NOT EXISTS idx_ai_conversations_user ON ai_conversations(user_id);
        CREATE INDEX IF NOT EXISTS idx_ai_messages_conversation ON ai_messages_history(conversation_id);

        -- Book indexes
        CREATE INDEX IF NOT EXISTS idx_chapters_book ON book_chapters(book_id);
        CREATE INDEX IF NOT EXISTS idx_chapter_content_chapter ON book_chapter_content(chapter_id);
        CREATE INDEX IF NOT EXISTS idx_characters_book ON book_characters(book_id);
        CREATE INDEX IF NOT EXISTS idx_character_attrs_character ON book_characters_attributes(character_id);
        CREATE INDEX IF NOT EXISTS idx_world_book ON book_world(book_id);
        CREATE INDEX IF NOT EXISTS idx_world_elements_world ON book_world_elements(world_id);
        CREATE INDEX IF NOT EXISTS idx_book_tools_book ON book_tools(book_id);
        CREATE INDEX IF NOT EXISTS idx_book_tools_user ON book_tools(user_id);
        CREATE INDEX IF NOT EXISTS idx_spell_tags_book ON book_spell_tags(book_id);
        CREATE INDEX IF NOT EXISTS idx_spell_tags_user ON book_spell_tags(user_id);
        CREATE INDEX IF NOT EXISTS idx_spells_book ON book_spells(book_id);
        CREATE INDEX IF NOT EXISTS idx_spells_user ON book_spells(user_id);

        -- Series indexes
        CREATE INDEX IF NOT EXISTS idx_book_series_user ON book_series(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_books_book ON series_books(book_id);
        CREATE INDEX IF NOT EXISTS idx_series_characters_series ON series_characters(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_characters_user ON series_characters(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_char_attrs_character ON series_characters_attributes(character_id);
        CREATE INDEX IF NOT EXISTS idx_series_char_attrs_user ON series_characters_attributes(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_worlds_series ON series_worlds(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_worlds_user ON series_worlds(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_world_elements_world ON series_world_elements(world_id);
        CREATE INDEX IF NOT EXISTS idx_series_world_elements_user ON series_world_elements(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_locations_series ON series_locations(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_locations_user ON series_locations(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_elements_location ON series_location_elements(location_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_elements_user ON series_location_elements(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_element ON series_location_sub_elements(element_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_user ON series_location_sub_elements(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_spells_series ON series_spells(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_spells_user ON series_spells(user_id);
        CREATE INDEX IF NOT EXISTS idx_series_spell_tags_series ON series_spell_tags(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_spell_tags_user ON series_spell_tags(user_id);

        -- Removed items indexes
        CREATE INDEX IF NOT EXISTS idx_removed_items_user ON removed_items(user_id);
        CREATE INDEX IF NOT EXISTS idx_removed_items_book ON removed_items(book_id);
        CREATE INDEX IF NOT EXISTS idx_removed_items_deleted_at ON removed_items(deleted_at);
        CREATE UNIQUE INDEX IF NOT EXISTS idx_removed_items_entity ON removed_items(table_name, entity_id);
        ",
    )?;

    Ok(())
}

// =============================================================================
// MIGRATION HELPERS
// =============================================================================

/// Check if a column exists in a table
fn column_exists(conn: &Connection, table: &str, column: &str) -> Result<bool, rusqlite::Error> {
    let sql = format!("PRAGMA table_info({})", table);
    let mut stmt = conn.prepare(&sql)?;
    let rows = stmt.query_map([], |row| row.get::<_, String>(1))?;
    for name in rows {
        if name? == column {
            return Ok(true);
        }
    }
    Ok(false)
}

/// Add a column to a table if it does not already exist
fn add_column(
    conn: &Connection,
    table: &str,
    column: &str,
    col_type: &str,
) -> Result<(), rusqlite::Error> {
    if !column_exists(conn, table, column)? {
        let sql = format!("ALTER TABLE {} ADD COLUMN {} {}", table, column, col_type);
        conn.execute_batch(&sql)?;
    }
    Ok(())
}

/// Get the database schema version using PRAGMA user_version
fn get_db_version(conn: &Connection) -> Result<u32, rusqlite::Error> {
    conn.query_row("PRAGMA user_version", [], |row| row.get(0))
}

/// Set the database schema version using PRAGMA user_version
fn set_db_version(conn: &Connection, version: u32) -> Result<(), rusqlite::Error> {
    conn.execute_batch(&format!("PRAGMA user_version = {}", version))
}

/// Check if the old _schema_version table exists
fn has_old_schema_table(conn: &Connection) -> Result<bool, rusqlite::Error> {
    let count: u32 = conn.query_row(
        "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='_schema_version'",
        [],
        |row| row.get(0),
    )?;
    Ok(count > 0)
}

/// Get version from the old _schema_version table
fn get_old_schema_version(conn: &Connection) -> Result<u32, rusqlite::Error> {
    match conn.query_row(
        "SELECT version FROM _schema_version LIMIT 1",
        [],
        |row| row.get(0),
    ) {
        Ok(v) => Ok(v),
        Err(_) => Ok(0),
    }
}

// =============================================================================
// OLD SYSTEM MIGRATION
// =============================================================================

/// Migrate from old _schema_version table to PRAGMA user_version.
/// Old system: v3 = all migrations done (book_tools created, NOT NULL fixes applied).
/// New system: v1 = equivalent starting point.
fn migrate_from_old_system(conn: &Connection) -> Result<(), rusqlite::Error> {
    let old_version = get_old_schema_version(conn)?;

    // Old v3 means all previous migrations were done
    // Map to new system: old v3 = new v1
    if old_version >= 3 {
        set_db_version(conn, SCHEMA_VERSION)?;
    }

    // Add last_update column to book_tools if missing (was added after v3)
    add_column(conn, "book_tools", "last_update", "INTEGER DEFAULT 0")?;

    // Add spells_enabled column to book_tools if missing
    add_column(
        conn,
        "book_tools",
        "spells_enabled",
        "INTEGER NOT NULL DEFAULT 0",
    )?;

    // Add new character fields if missing
    add_column(conn, "book_characters", "nickname", "TEXT DEFAULT NULL")?;
    add_column(conn, "book_characters", "age", "TEXT DEFAULT NULL")?;
    add_column(conn, "book_characters", "gender", "TEXT DEFAULT NULL")?;
    add_column(conn, "book_characters", "species", "TEXT DEFAULT NULL")?;
    add_column(
        conn,
        "book_characters",
        "nationality",
        "TEXT DEFAULT NULL",
    )?;
    add_column(conn, "book_characters", "status", "TEXT DEFAULT NULL")?;
    add_column(
        conn,
        "book_characters",
        "speech_pattern",
        "TEXT DEFAULT NULL",
    )?;
    add_column(
        conn,
        "book_characters",
        "catchphrase",
        "TEXT DEFAULT NULL",
    )?;
    add_column(conn, "book_characters", "residence", "TEXT DEFAULT NULL")?;
    add_column(conn, "book_characters", "notes", "TEXT DEFAULT NULL")?;
    add_column(conn, "book_characters", "color", "TEXT DEFAULT NULL")?;

    // Create book_spell_tags table if missing
    conn.execute_batch(
        "
        CREATE TABLE IF NOT EXISTS book_spell_tags (
            tag_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_spell_tags_book ON book_spell_tags(book_id);
        CREATE INDEX IF NOT EXISTS idx_spell_tags_user ON book_spell_tags(user_id);
        ",
    )?;

    // Create book_spells table if missing
    conn.execute_batch(
        "
        CREATE TABLE IF NOT EXISTS book_spells (
            spell_id TEXT PRIMARY KEY,
            book_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            description TEXT,
            appearance TEXT,
            tags TEXT,
            power_level TEXT,
            components TEXT,
            limitations TEXT,
            notes TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_spells_book ON book_spells(book_id);
        CREATE INDEX IF NOT EXISTS idx_spells_user ON book_spells(user_id);
        ",
    )?;

    // Create series tables (v3)
    conn.execute_batch(
        "
        CREATE TABLE IF NOT EXISTS book_series (
            series_id TEXT PRIMARY KEY,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            description TEXT,
            cover_image TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (user_id) REFERENCES erit_users(user_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_book_series_user ON book_series(user_id);

        CREATE TABLE IF NOT EXISTS series_books (
            series_id TEXT NOT NULL,
            book_id TEXT NOT NULL,
            book_order INTEGER NOT NULL DEFAULT 1,
            last_update INTEGER DEFAULT 0,
            PRIMARY KEY (series_id, book_id),
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE,
            FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_books_book ON series_books(book_id);

        CREATE TABLE IF NOT EXISTS series_characters (
            character_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            first_name TEXT NOT NULL,
            last_name TEXT,
            nickname TEXT,
            age TEXT,
            gender TEXT,
            species TEXT,
            nationality TEXT,
            status TEXT,
            category TEXT NOT NULL,
            title TEXT,
            image TEXT,
            role TEXT,
            biography TEXT,
            history TEXT,
            speech_pattern TEXT,
            catchphrase TEXT,
            residence TEXT,
            notes TEXT,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_characters_series ON series_characters(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_characters_user ON series_characters(user_id);

        CREATE TABLE IF NOT EXISTS series_characters_attributes (
            attr_id TEXT PRIMARY KEY,
            character_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            attribute_name TEXT NOT NULL,
            attribute_value TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (character_id) REFERENCES series_characters(character_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_char_attrs_character ON series_characters_attributes(character_id);
        CREATE INDEX IF NOT EXISTS idx_series_char_attrs_user ON series_characters_attributes(user_id);

        CREATE TABLE IF NOT EXISTS series_worlds (
            world_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            history TEXT,
            politics TEXT,
            economy TEXT,
            religion TEXT,
            languages TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_worlds_series ON series_worlds(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_worlds_user ON series_worlds(user_id);

        CREATE TABLE IF NOT EXISTS series_world_elements (
            element_id TEXT PRIMARY KEY,
            world_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_type INTEGER NOT NULL,
            name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (world_id) REFERENCES series_worlds(world_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_world_elements_world ON series_world_elements(world_id);
        CREATE INDEX IF NOT EXISTS idx_series_world_elements_user ON series_world_elements(user_id);

        CREATE TABLE IF NOT EXISTS series_locations (
            loc_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            loc_name TEXT NOT NULL,
            loc_original_name TEXT NOT NULL,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_locations_series ON series_locations(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_locations_user ON series_locations(user_id);

        CREATE TABLE IF NOT EXISTS series_location_elements (
            element_id TEXT PRIMARY KEY,
            location_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            element_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            element_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (location_id) REFERENCES series_locations(loc_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_loc_elements_location ON series_location_elements(location_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_elements_user ON series_location_elements(user_id);

        CREATE TABLE IF NOT EXISTS series_location_sub_elements (
            sub_element_id TEXT PRIMARY KEY,
            element_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            sub_elem_name TEXT NOT NULL,
            original_name TEXT NOT NULL,
            sub_elem_description TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (element_id) REFERENCES series_location_elements(element_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_element ON series_location_sub_elements(element_id);
        CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_user ON series_location_sub_elements(user_id);

        CREATE TABLE IF NOT EXISTS series_spells (
            spell_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            name_hash TEXT NOT NULL,
            description TEXT,
            appearance TEXT,
            tags TEXT,
            power_level TEXT,
            components TEXT,
            limitations TEXT,
            notes TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_spells_series ON series_spells(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_spells_user ON series_spells(user_id);

        CREATE TABLE IF NOT EXISTS series_spell_tags (
            tag_id TEXT PRIMARY KEY,
            series_id TEXT NOT NULL,
            user_id TEXT NOT NULL,
            name TEXT NOT NULL,
            hashed_name TEXT NOT NULL,
            color TEXT,
            last_update INTEGER DEFAULT 0,
            FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
        );
        CREATE INDEX IF NOT EXISTS idx_series_spell_tags_series ON series_spell_tags(series_id);
        CREATE INDEX IF NOT EXISTS idx_series_spell_tags_user ON series_spell_tags(user_id);
        ",
    )?;

    // Add series_*_id columns to existing book tables (v3)
    add_column(
        conn,
        "book_characters",
        "series_character_id",
        "TEXT DEFAULT NULL",
    )?;
    add_column(conn, "book_world", "series_world_id", "TEXT DEFAULT NULL")?;
    add_column(
        conn,
        "book_location",
        "series_location_id",
        "TEXT DEFAULT NULL",
    )?;
    add_column(
        conn,
        "book_spells",
        "series_spell_id",
        "TEXT DEFAULT NULL",
    )?;

    // Removed Items (sync deletion tracking)
    conn.execute_batch(
        "
        CREATE TABLE IF NOT EXISTS removed_items (
            removal_id TEXT PRIMARY KEY,
            table_name TEXT NOT NULL,
            entity_id TEXT NOT NULL,
            book_id TEXT,
            user_id TEXT NOT NULL,
            deleted_at INTEGER NOT NULL,
            removed_time INTEGER NOT NULL DEFAULT 0
        );
        CREATE INDEX IF NOT EXISTS idx_removed_items_user ON removed_items(user_id);
        CREATE INDEX IF NOT EXISTS idx_removed_items_book ON removed_items(book_id);
        CREATE INDEX IF NOT EXISTS idx_removed_items_deleted_at ON removed_items(deleted_at);
        CREATE UNIQUE INDEX IF NOT EXISTS idx_removed_items_entity ON removed_items(table_name, entity_id);
        ",
    )?;

    // Drop old schema version table
    conn.execute_batch("DROP TABLE IF EXISTS _schema_version;")?;

    Ok(())
}

// =============================================================================
// VERSIONED MIGRATIONS
// =============================================================================

/// Run version-based migrations on an existing database.
/// In dev mode, call `run_dev_queries` first then return.
/// In prod, runs versioned migrations (v1, v2, v3).
pub fn run_migrations(conn: &Connection) -> Result<(), rusqlite::Error> {
    // Migrate from old _schema_version system to PRAGMA user_version
    if has_old_schema_table(conn)? {
        migrate_from_old_system(conn)?;
        return Ok(());
    }

    let current_version = get_db_version(conn)?;
    if current_version >= SCHEMA_VERSION {
        return Ok(());
    }

    // v1 - book_tools table + spell book tables (for fresh DBs or DBs without old system)
    if current_version < 1 {
        conn.execute_batch(
            "
            -- Book Tools
            CREATE TABLE IF NOT EXISTS book_tools (
                book_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                characters_enabled INTEGER NOT NULL DEFAULT 0,
                worlds_enabled INTEGER NOT NULL DEFAULT 0,
                locations_enabled INTEGER NOT NULL DEFAULT 0,
                spells_enabled INTEGER NOT NULL DEFAULT 0,
                last_update INTEGER DEFAULT 0,
                UNIQUE (book_id, user_id),
                FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_book_tools_book ON book_tools(book_id);
            CREATE INDEX IF NOT EXISTS idx_book_tools_user ON book_tools(user_id);

            -- Book Spell Tags
            CREATE TABLE IF NOT EXISTS book_spell_tags (
                tag_id TEXT PRIMARY KEY,
                book_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                name_hash TEXT NOT NULL,
                color TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_spell_tags_book ON book_spell_tags(book_id);
            CREATE INDEX IF NOT EXISTS idx_spell_tags_user ON book_spell_tags(user_id);

            -- Book Spells
            CREATE TABLE IF NOT EXISTS book_spells (
                spell_id TEXT PRIMARY KEY,
                book_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                name_hash TEXT NOT NULL,
                description TEXT,
                appearance TEXT,
                tags TEXT,
                power_level TEXT,
                components TEXT,
                limitations TEXT,
                notes TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_spells_book ON book_spells(book_id);
            CREATE INDEX IF NOT EXISTS idx_spells_user ON book_spells(user_id);
            ",
        )?;
    }

    // v2 - Add new character fields (nickname, age, gender, species, nationality, status, etc.)
    if current_version < 2 {
        add_column(conn, "book_characters", "nickname", "TEXT DEFAULT NULL")?;
        add_column(conn, "book_characters", "age", "TEXT DEFAULT NULL")?;
        add_column(conn, "book_characters", "gender", "TEXT DEFAULT NULL")?;
        add_column(conn, "book_characters", "species", "TEXT DEFAULT NULL")?;
        add_column(
            conn,
            "book_characters",
            "nationality",
            "TEXT DEFAULT NULL",
        )?;
        add_column(conn, "book_characters", "status", "TEXT DEFAULT NULL")?;
        add_column(
            conn,
            "book_characters",
            "speech_pattern",
            "TEXT DEFAULT NULL",
        )?;
        add_column(
            conn,
            "book_characters",
            "catchphrase",
            "TEXT DEFAULT NULL",
        )?;
        add_column(conn, "book_characters", "residence", "TEXT DEFAULT NULL")?;
        add_column(conn, "book_characters", "notes", "TEXT DEFAULT NULL")?;
        add_column(conn, "book_characters", "color", "TEXT DEFAULT NULL")?;
    }

    // v3 - Add series tables and series_*_id columns to existing book tables
    if current_version < 3 {
        // Create series tables (order matters for foreign keys)
        conn.execute_batch(
            "
            -- Book Series (main series table)
            CREATE TABLE IF NOT EXISTS book_series (
                series_id TEXT PRIMARY KEY,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                hashed_name TEXT NOT NULL,
                description TEXT,
                cover_image TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (user_id) REFERENCES erit_users(user_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_book_series_user ON book_series(user_id);

            -- Series Books (link series to books with order)
            CREATE TABLE IF NOT EXISTS series_books (
                series_id TEXT NOT NULL,
                book_id TEXT NOT NULL,
                book_order INTEGER NOT NULL DEFAULT 1,
                last_update INTEGER DEFAULT 0,
                PRIMARY KEY (series_id, book_id),
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE,
                FOREIGN KEY (book_id) REFERENCES erit_books(book_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_books_book ON series_books(book_id);

            -- Series Characters
            CREATE TABLE IF NOT EXISTS series_characters (
                character_id TEXT PRIMARY KEY,
                series_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                first_name TEXT NOT NULL,
                last_name TEXT,
                nickname TEXT,
                age TEXT,
                gender TEXT,
                species TEXT,
                nationality TEXT,
                status TEXT,
                category TEXT NOT NULL,
                title TEXT,
                image TEXT,
                role TEXT,
                biography TEXT,
                history TEXT,
                speech_pattern TEXT,
                catchphrase TEXT,
                residence TEXT,
                notes TEXT,
                color TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_characters_series ON series_characters(series_id);
            CREATE INDEX IF NOT EXISTS idx_series_characters_user ON series_characters(user_id);

            -- Series Characters Attributes
            CREATE TABLE IF NOT EXISTS series_characters_attributes (
                attr_id TEXT PRIMARY KEY,
                character_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                attribute_name TEXT NOT NULL,
                attribute_value TEXT NOT NULL,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (character_id) REFERENCES series_characters(character_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_char_attrs_character ON series_characters_attributes(character_id);
            CREATE INDEX IF NOT EXISTS idx_series_char_attrs_user ON series_characters_attributes(user_id);

            -- Series Worlds
            CREATE TABLE IF NOT EXISTS series_worlds (
                world_id TEXT PRIMARY KEY,
                series_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                hashed_name TEXT NOT NULL,
                history TEXT,
                politics TEXT,
                economy TEXT,
                religion TEXT,
                languages TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_worlds_series ON series_worlds(series_id);
            CREATE INDEX IF NOT EXISTS idx_series_worlds_user ON series_worlds(user_id);

            -- Series World Elements
            CREATE TABLE IF NOT EXISTS series_world_elements (
                element_id TEXT PRIMARY KEY,
                world_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                element_type INTEGER NOT NULL,
                name TEXT NOT NULL,
                original_name TEXT NOT NULL,
                description TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (world_id) REFERENCES series_worlds(world_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_world_elements_world ON series_world_elements(world_id);
            CREATE INDEX IF NOT EXISTS idx_series_world_elements_user ON series_world_elements(user_id);

            -- Series Locations
            CREATE TABLE IF NOT EXISTS series_locations (
                loc_id TEXT PRIMARY KEY,
                series_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                loc_name TEXT NOT NULL,
                loc_original_name TEXT NOT NULL,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_locations_series ON series_locations(series_id);
            CREATE INDEX IF NOT EXISTS idx_series_locations_user ON series_locations(user_id);

            -- Series Location Elements
            CREATE TABLE IF NOT EXISTS series_location_elements (
                element_id TEXT PRIMARY KEY,
                location_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                element_name TEXT NOT NULL,
                original_name TEXT NOT NULL,
                element_description TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (location_id) REFERENCES series_locations(loc_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_loc_elements_location ON series_location_elements(location_id);
            CREATE INDEX IF NOT EXISTS idx_series_loc_elements_user ON series_location_elements(user_id);

            -- Series Location Sub Elements
            CREATE TABLE IF NOT EXISTS series_location_sub_elements (
                sub_element_id TEXT PRIMARY KEY,
                element_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                sub_elem_name TEXT NOT NULL,
                original_name TEXT NOT NULL,
                sub_elem_description TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (element_id) REFERENCES series_location_elements(element_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_element ON series_location_sub_elements(element_id);
            CREATE INDEX IF NOT EXISTS idx_series_loc_sub_elements_user ON series_location_sub_elements(user_id);

            -- Series Spells
            CREATE TABLE IF NOT EXISTS series_spells (
                spell_id TEXT PRIMARY KEY,
                series_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                name_hash TEXT NOT NULL,
                description TEXT,
                appearance TEXT,
                tags TEXT,
                power_level TEXT,
                components TEXT,
                limitations TEXT,
                notes TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_spells_series ON series_spells(series_id);
            CREATE INDEX IF NOT EXISTS idx_series_spells_user ON series_spells(user_id);

            -- Series Spell Tags
            CREATE TABLE IF NOT EXISTS series_spell_tags (
                tag_id TEXT PRIMARY KEY,
                series_id TEXT NOT NULL,
                user_id TEXT NOT NULL,
                name TEXT NOT NULL,
                hashed_name TEXT NOT NULL,
                color TEXT,
                last_update INTEGER DEFAULT 0,
                FOREIGN KEY (series_id) REFERENCES book_series(series_id) ON DELETE CASCADE
            );
            CREATE INDEX IF NOT EXISTS idx_series_spell_tags_series ON series_spell_tags(series_id);
            CREATE INDEX IF NOT EXISTS idx_series_spell_tags_user ON series_spell_tags(user_id);

            -- Removed Items (sync deletion tracking)
            CREATE TABLE IF NOT EXISTS removed_items (
                removal_id TEXT PRIMARY KEY,
                table_name TEXT NOT NULL,
                entity_id TEXT NOT NULL,
                book_id TEXT,
                user_id TEXT NOT NULL,
                deleted_at INTEGER NOT NULL,
                removed_time INTEGER NOT NULL DEFAULT 0
            );
            CREATE INDEX IF NOT EXISTS idx_removed_items_user ON removed_items(user_id);
            CREATE INDEX IF NOT EXISTS idx_removed_items_book ON removed_items(book_id);
            CREATE INDEX IF NOT EXISTS idx_removed_items_deleted_at ON removed_items(deleted_at);
            CREATE UNIQUE INDEX IF NOT EXISTS idx_removed_items_entity ON removed_items(table_name, entity_id);
            ",
        )?;

        // Add series_*_id columns to existing book tables
        add_column(
            conn,
            "book_characters",
            "series_character_id",
            "TEXT DEFAULT NULL",
        )?;
        add_column(conn, "book_world", "series_world_id", "TEXT DEFAULT NULL")?;
        add_column(
            conn,
            "book_location",
            "series_location_id",
            "TEXT DEFAULT NULL",
        )?;
        add_column(
            conn,
            "book_spells",
            "series_spell_id",
            "TEXT DEFAULT NULL",
        )?;
    }

    set_db_version(conn, SCHEMA_VERSION)?;

    Ok(())
}

// =============================================================================
// DEV QUERIES
// =============================================================================

/// DEV ONLY - Ensures schema is up-to-date in dev mode.
/// Delegates to run_migrations which is already idempotent
/// (uses IF NOT EXISTS and column_exists checks).
pub fn run_dev_queries(conn: &Connection) {
    let _ = run_migrations(conn);
}


