"""
Database initialization script for MTG Online backend.

Creates all necessary tables matching the SQLAlchemy ORM models
for both databases.
"""
import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import text
from app.core.settings import get_settings


async def setup_mtg_online_database():
    """Create tables for the mtgonline database."""
    settings = get_settings()
    engine = create_async_engine(settings.MTGO_DATABASE_URL)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
    
    async with async_session() as session:
        # Create tables
        tables = [
            """
            CREATE TABLE IF NOT EXISTS mtgonline_users (
                id SERIAL PRIMARY KEY,
                username VARCHAR(64) UNIQUE NOT NULL,
                password_hash VARCHAR(128) NOT NULL,
                salt VARCHAR(128) NOT NULL,
                email VARCHAR(255),
                country VARCHAR(2),
                real_name VARCHAR(128),
                avatar_bmp TEXT,
                privlevel VARCHAR(50) DEFAULT 'User',
                is_active BOOLEAN DEFAULT TRUE,
                is_banned BOOLEAN DEFAULT FALSE,
                ban_reason TEXT,
                ban_ends TIMESTAMP,
                vip_status INTEGER DEFAULT 0,
                vip_expiry TIMESTAMP,
                creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                last_login TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_decklist_folders (
                id SERIAL PRIMARY KEY,
                owner_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
                name VARCHAR(255) NOT NULL,
                parent_id INTEGER REFERENCES mtgonline_decklist_folders(id) ON DELETE CASCADE,
                creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_decklist_files (
                id SERIAL PRIMARY KEY,
                folder_id INTEGER REFERENCES mtgonline_decklist_folders(id) ON DELETE CASCADE,
                owner_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
                name VARCHAR(255) NOT NULL,
                content TEXT NOT NULL,
                format VARCHAR(50) DEFAULT 'native',
                creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_rooms (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) UNIQUE NOT NULL,
                description TEXT,
                is_password_protected BOOLEAN DEFAULT FALSE,
                password_hash VARCHAR(128),
                creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_rooms_gametypes (
                id SERIAL PRIMARY KEY,
                room_id INTEGER REFERENCES mtgonline_rooms(id) ON DELETE CASCADE,
                name VARCHAR(100) NOT NULL,
                description TEXT
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_bans (
                id SERIAL PRIMARY KEY,
                user_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
                server_id INTEGER,
                reason TEXT NOT NULL,
                moderators VARCHAR(255),
                ip_address VARCHAR(45),
                expiration_time TIMESTAMP,
                active BOOLEAN DEFAULT TRUE,
                creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_log (
                id SERIAL PRIMARY KEY,
                room_id INTEGER REFERENCES mtgonline_rooms(id) ON DELETE CASCADE,
                player_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
                message TEXT NOT NULL,
                timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtgonline_audit (
                id SERIAL PRIMARY KEY,
                admin_id INTEGER REFERENCES mtgonline_users(id) ON DELETE SET NULL,
                action_type VARCHAR(50) NOT NULL,
                target_user_id INTEGER REFERENCES mtgonline_users(id) ON DELETE SET NULL,
                details TEXT,
                ip_address VARCHAR(45),
                timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
        ]
        
        for table_sql in tables:
            await session.execute(text(table_sql))
        
        # Create indexes
        indexes = [
            "CREATE INDEX IF NOT EXISTS idx_decks_owner ON mtgonline_decklist_files(owner_id);",
            "CREATE INDEX IF NOT EXISTS idx_decks_folder ON mtgonline_decklist_files(folder_id);",
            "CREATE INDEX IF NOT EXISTS idx_bans_active ON mtgonline_bans(active);",
            "CREATE INDEX IF NOT EXISTS idx_log_timestamp ON mtgonline_log(timestamp);",
        ]
        
        for idx_sql in indexes:
            await session.execute(text(idx_sql))
        
        print("✓ All mtgonline tables created")
    
    await engine.dispose()


async def setup_mtg_data_database():
    """Create tables for the mtgdata database."""
    settings = get_settings()
    engine = create_async_engine(settings.MTG_DATABASE_URL)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
    
    async with async_session() as session:
        # Create tables
        tables = [
            """
            CREATE TABLE IF NOT EXISTS mtg_sets (
                id SERIAL PRIMARY KEY,
                code VARCHAR(10) UNIQUE NOT NULL,
                name VARCHAR(255),
                type VARCHAR(100),
                release_date DATE,
                base_set_size INTEGER,
                total_size INTEGER,
                is_foil_only BOOLEAN,
                is_non_foil_only BOOLEAN,
                digital BOOLEAN,
                icon_svg_url TEXT,
                parent_code VARCHAR(10),
                mtgo_code VARCHAR(10),
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
            """
            CREATE TABLE IF NOT EXISTS mtg_cards (
                id SERIAL PRIMARY KEY,
                set_id INTEGER REFERENCES mtg_sets(id) ON DELETE CASCADE,
                name VARCHAR(255),
                mana_cost VARCHAR(255),
                type_line VARCHAR(255),
                oracle_text TEXT,
                power VARCHAR(50),
                toughness VARCHAR(50),
                rarity VARCHAR(50),
                layout VARCHAR(50),
                artist VARCHAR(255),
                flavor_text TEXT,
                numbers VARCHAR(100),
                identifiers TEXT,
                images TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """,
        ]
        
        for table_sql in tables:
            await session.execute(text(table_sql))
        
        # Create indexes
        indexes = [
            "CREATE INDEX IF NOT EXISTS idx_mtg_cards_name ON mtg_cards(name);",
            "CREATE INDEX IF NOT EXISTS idx_mtg_cards_type ON mtg_cards(type_line);",
            "CREATE INDEX IF NOT EXISTS idx_mtg_cards_rarity ON mtg_cards(rarity);",
            "CREATE INDEX IF NOT EXISTS idx_mtg_cards_set_id ON mtg_cards(set_id);",
        ]
        
        for idx_sql in indexes:
            await session.execute(text(idx_sql))
        
        print("✓ All mtgdata tables created")
    
    await engine.dispose()


async def main():
    """Main initialization function."""
    print("MTG Online Database Initialization")
    print("=" * 50)
    
    # Setup mtgonline database
    print("\nSetting up mtgonline database...")
    await setup_mtg_online_database()
    
    # Setup mtgdata database
    print("\nSetting up mtgdata database...")
    await setup_mtg_data_database()
    
    print("\n✓ Database initialization complete!")


if __name__ == "__main__":
    asyncio.run(main())
