"""Add all missing user columns that were manually fixed

Revision ID: fix_missing_user_columns
Revises: dc3c13ef2107
Create Date: 2025-08-20 17:26:00.000000

This migration captures all the columns that were manually added to production
during the 16-hour debugging session. These columns are already in production
but need to be in a migration for consistency.
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'fix_missing_user_columns'
down_revision = 'dc3c13ef2107'
branch_labels = None
depends_on = None


def upgrade():
    # Check if the users table exists before trying to inspect it
    conn = op.get_bind()
    inspector = sa.inspect(conn)
    
    # Only proceed if the users table exists
    if 'users' in inspector.get_table_names():
        existing_columns = [col['name'] for col in inspector.get_columns('users')]
        
        # Add all the columns that were manually fixed (if they don't exist)
        with op.batch_alter_table('users', schema=None) as batch_op:
            if 'role' not in existing_columns:
                batch_op.add_column(sa.Column('role', sa.String(50), nullable=True, server_default='worker'))
            if 'username' not in existing_columns:
                batch_op.add_column(sa.Column('username', sa.String(150), nullable=True))
            if 'is_verified' not in existing_columns:
                batch_op.add_column(sa.Column('is_verified', sa.Boolean(), nullable=True, server_default='false'))
            if 'abn' not in existing_columns:
                batch_op.add_column(sa.Column('abn', sa.String(20), nullable=True))
            if 'company_name' not in existing_columns:
                batch_op.add_column(sa.Column('company_name', sa.String(200), nullable=True))
            if 'phone' not in existing_columns:
                batch_op.add_column(sa.Column('phone', sa.String(20), nullable=True))
            if 'address' not in existing_columns:
                batch_op.add_column(sa.Column('address', sa.Text(), nullable=True))
            if 'bio' not in existing_columns:
                batch_op.add_column(sa.Column('bio', sa.Text(), nullable=True))
            if 'skills' not in existing_columns:
                batch_op.add_column(sa.Column('skills', sa.Text(), nullable=True))
            if 'certifications' not in existing_columns:
                batch_op.add_column(sa.Column('certifications', sa.Text(), nullable=True))
            if 'insurance_details' not in existing_columns:
                batch_op.add_column(sa.Column('insurance_details', sa.Text(), nullable=True))
            if 'license_number' not in existing_columns:
                batch_op.add_column(sa.Column('license_number', sa.String(100), nullable=True))
            if 'years_experience' not in existing_columns:
                batch_op.add_column(sa.Column('years_experience', sa.Integer(), nullable=True, server_default='0'))
            if 'portfolio_url' not in existing_columns:
                batch_op.add_column(sa.Column('portfolio_url', sa.String(500), nullable=True))
            if 'hourly_rate' not in existing_columns:
                batch_op.add_column(sa.Column('hourly_rate', sa.Numeric(10, 2), nullable=True))
            if 'availability_status' not in existing_columns:
                batch_op.add_column(sa.Column('availability_status', sa.String(50), nullable=True, server_default='available'))
            if 'rating' not in existing_columns:
                batch_op.add_column(sa.Column('rating', sa.Numeric(3, 2), nullable=True, server_default='0.00'))
            if 'total_reviews' not in existing_columns:
                batch_op.add_column(sa.Column('total_reviews', sa.Integer(), nullable=True, server_default='0'))
            if 'completed_jobs' not in existing_columns:
                batch_op.add_column(sa.Column('completed_jobs', sa.Integer(), nullable=True, server_default='0'))
            if 'verification_token' not in existing_columns:
                batch_op.add_column(sa.Column('verification_token', sa.String(100), nullable=True))
            if 'verification_token_expiry' not in existing_columns:
                batch_op.add_column(sa.Column('verification_token_expiry', sa.DateTime(), nullable=True))
            if 'reset_token' not in existing_columns:
                batch_op.add_column(sa.Column('reset_token', sa.String(100), nullable=True))
            if 'reset_token_expiry' not in existing_columns:
                batch_op.add_column(sa.Column('reset_token_expiry', sa.DateTime(), nullable=True))
            if 'last_login' not in existing_columns:
                batch_op.add_column(sa.Column('last_login', sa.DateTime(), nullable=True))
            if 'account_status' not in existing_columns:
                batch_op.add_column(sa.Column('account_status', sa.String(50), nullable=True, server_default='active'))
            if 'profile_picture' not in existing_columns:
                batch_op.add_column(sa.Column('profile_picture', sa.String(500), nullable=True))
            if 'stripe_customer_id' not in existing_columns:
                batch_op.add_column(sa.Column('stripe_customer_id', sa.String(255), nullable=True))
            if 'stripe_account_id' not in existing_columns:
                batch_op.add_column(sa.Column('stripe_account_id', sa.String(255), nullable=True))
            if 'two_factor_secret' not in existing_columns:
                batch_op.add_column(sa.Column('two_factor_secret', sa.String(32), nullable=True))
            if 'two_factor_enabled' not in existing_columns:
                batch_op.add_column(sa.Column('two_factor_enabled', sa.Boolean(), nullable=True, server_default='false'))
    
    # Create user_sessions table if it doesn't exist
    if 'user_sessions' not in inspector.get_table_names():
        op.create_table('user_sessions',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('user_id', sa.Integer(), nullable=False),
            sa.Column('session_token', sa.String(255), nullable=False),
            sa.Column('ip_address', sa.String(45), nullable=True),
            sa.Column('user_agent', sa.Text(), nullable=True),
            sa.Column('created_at', sa.DateTime(), nullable=True, server_default=sa.func.now()),
            sa.Column('expires_at', sa.DateTime(), nullable=False),
            sa.Column('is_active', sa.Boolean(), nullable=True, server_default='true'),
            sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
            sa.PrimaryKeyConstraint('id'),
            sa.UniqueConstraint('session_token')
        )


def downgrade():
    # Drop user_sessions table if it exists
    op.drop_table('user_sessions', if_exists=True)
    
    # Remove all the added columns
    with op.batch_alter_table('users', schema=None) as batch_op:
        batch_op.drop_column('two_factor_enabled')
        batch_op.drop_column('two_factor_secret')
        batch_op.drop_column('stripe_account_id')
        batch_op.drop_column('stripe_customer_id')
        batch_op.drop_column('profile_picture')
        batch_op.drop_column('account_status')
        batch_op.drop_column('last_login')
        batch_op.drop_column('reset_token_expiry')
        batch_op.drop_column('reset_token')
        batch_op.drop_column('verification_token_expiry')
        batch_op.drop_column('verification_token')
        batch_op.drop_column('completed_jobs')
        batch_op.drop_column('total_reviews')
        batch_op.drop_column('rating')
        batch_op.drop_column('availability_status')
        batch_op.drop_column('hourly_rate')
        batch_op.drop_column('portfolio_url')
        batch_op.drop_column('years_experience')
        batch_op.drop_column('license_number')
        batch_op.drop_column('insurance_details')
        batch_op.drop_column('certifications')
        batch_op.drop_column('skills')
        batch_op.drop_column('bio')
        batch_op.drop_column('address')
        batch_op.drop_column('phone')
        batch_op.drop_column('company_name')
        batch_op.drop_column('abn')
        batch_op.drop_column('is_verified')
        batch_op.drop_column('username')
        batch_op.drop_column('role')
