"""add_email_verification_and_enhance_user_security

Revision ID: fe519abcefe7
Revises: 54e4d0db31a3
Create Date: 2025-12-06 01:53:10.797944

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql


# revision identifiers, used by Alembic.
revision = 'fe519abcefe7'
down_revision = '54e4d0db31a3'
branch_labels = None
depends_on = None


def upgrade() -> None:
    bind = op.get_bind()
    inspector = sa.inspect(bind)
    tables = inspector.get_table_names()
    
    # Add email_verified column to users table
    if 'users' in tables:
        columns = [col['name'] for col in inspector.get_columns('users')]
        if 'email_verified' not in columns:
            # Use MySQL-compatible boolean default
            op.add_column('users', sa.Column('email_verified', sa.Boolean(), nullable=False, server_default=sa.text('0')))
            # Check if index exists before creating
            try:
                op.create_index('ix_users_email_verified', 'users', ['email_verified'], unique=False)
            except Exception:
                pass  # Index might already exist
        
        # Add password expiry fields
        if 'password_changed_at' not in columns:
            op.add_column('users', sa.Column('password_changed_at', sa.DateTime(), nullable=True))
            # Check if index exists before creating
            try:
                op.create_index('ix_users_password_changed_at', 'users', ['password_changed_at'], unique=False)
            except Exception:
                pass  # Index might already exist
    
    # Create password_history table
    if 'password_history' not in tables:
        op.create_table(
            'password_history',
            sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
            sa.Column('user_id', sa.Integer(), nullable=False),
            sa.Column('password_hash', sa.String(length=255), nullable=False),
            sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
            sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
            sa.PrimaryKeyConstraint('id')
        )
        op.create_index(op.f('ix_password_history_id'), 'password_history', ['id'], unique=False)
        op.create_index(op.f('ix_password_history_user_id'), 'password_history', ['user_id'], unique=False)
        op.create_index(op.f('ix_password_history_created_at'), 'password_history', ['created_at'], unique=False)
    
    # Create email_verification_tokens table
    if 'email_verification_tokens' not in tables:
        op.create_table(
            'email_verification_tokens',
            sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
            sa.Column('user_id', sa.Integer(), nullable=False),
            sa.Column('token', sa.String(length=255), nullable=False),
            sa.Column('email', sa.String(length=100), nullable=False),
            sa.Column('expires_at', sa.DateTime(), nullable=False),
            sa.Column('used', sa.Boolean(), nullable=False, server_default=sa.text('0')),
            sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
            sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')),
            sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
            sa.PrimaryKeyConstraint('id')
        )
        op.create_index(op.f('ix_email_verification_tokens_id'), 'email_verification_tokens', ['id'], unique=False)
        op.create_index(op.f('ix_email_verification_tokens_user_id'), 'email_verification_tokens', ['user_id'], unique=False)
        op.create_index(op.f('ix_email_verification_tokens_token'), 'email_verification_tokens', ['token'], unique=True)
        op.create_index(op.f('ix_email_verification_tokens_expires_at'), 'email_verification_tokens', ['expires_at'], unique=False)


def downgrade() -> None:
    bind = op.get_bind()
    inspector = sa.inspect(bind)
    tables = inspector.get_table_names()
    
    # Drop email_verification_tokens table
    if 'email_verification_tokens' in tables:
        op.drop_index(op.f('ix_email_verification_tokens_expires_at'), table_name='email_verification_tokens')
        op.drop_index(op.f('ix_email_verification_tokens_token'), table_name='email_verification_tokens')
        op.drop_index(op.f('ix_email_verification_tokens_user_id'), table_name='email_verification_tokens')
        op.drop_index(op.f('ix_email_verification_tokens_id'), table_name='email_verification_tokens')
        op.drop_table('email_verification_tokens')
    
    # Remove password_history table
    if 'password_history' in tables:
        op.drop_index(op.f('ix_password_history_created_at'), table_name='password_history')
        op.drop_index(op.f('ix_password_history_user_id'), table_name='password_history')
        op.drop_index(op.f('ix_password_history_id'), table_name='password_history')
        op.drop_table('password_history')
    
    # Remove email_verified and password_changed_at columns from users table
    if 'users' in tables:
        columns = [col['name'] for col in inspector.get_columns('users')]
        if 'password_changed_at' in columns:
            op.drop_index('ix_users_password_changed_at', table_name='users')
            op.drop_column('users', 'password_changed_at')
        if 'email_verified' in columns:
            op.drop_index('ix_users_email_verified', table_name='users')
            op.drop_column('users', 'email_verified')
