"""add file upload system

Revision ID: add_file_upload_001
Revises: add_password_reset
Create Date: 2025-11-05

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

# revision identifiers, used by Alembic.
revision = 'add_file_upload_001'
down_revision = 'add_password_reset'
branch_labels = None
depends_on = None


def upgrade():
    # Create enum types (skip if they already exist)
    conn = op.get_bind()
    
    # Check if storagebackend type exists
    result = conn.execute(sa.text(
        "SELECT 1 FROM pg_type WHERE typname = 'storagebackend'"
    )).fetchone()
    
    if not result:
        storage_backend = postgresql.ENUM(
            'LOCAL', 'CLOUDINARY', 'AZURE', 'S3',
            name='storagebackend'
        )
        storage_backend.create(conn)
    
    # Check if filecategory type exists
    result = conn.execute(sa.text(
        "SELECT 1 FROM pg_type WHERE typname = 'filecategory'"
    )).fetchone()
    
    if not result:
        file_category = postgresql.ENUM(
            'PROFILE_PICTURE', 'MESSAGE_ATTACHMENT', 'CONTRACT_DOCUMENT',
            'JOB_PHOTO', 'CERTIFICATION', 'INVOICE', 'INSURANCE_DOCUMENT', 'OTHER',
            name='filecategory'
        )
        file_category.create(conn)
    
    # Create file_uploads table
    op.create_table(
        'file_uploads',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('user_id', sa.Integer(), nullable=False),
        sa.Column('filename', sa.String(length=500), nullable=False),
        sa.Column('original_filename', sa.String(length=500), nullable=False),
        sa.Column('file_type', sa.String(length=100), nullable=True),
        sa.Column('file_size', sa.BigInteger(), nullable=True),
        sa.Column('storage_backend', postgresql.ENUM('LOCAL', 'CLOUDINARY', 'AZURE', 'S3', name='storagebackend', create_type=False), nullable=False, server_default='LOCAL'),
        sa.Column('storage_path', sa.Text(), nullable=True),
        sa.Column('public_url', sa.Text(), nullable=True),
        sa.Column('category', postgresql.ENUM('PROFILE_PICTURE', 'MESSAGE_ATTACHMENT', 'CONTRACT_DOCUMENT', 'JOB_PHOTO', 'CERTIFICATION', 'INVOICE', 'INSURANCE_DOCUMENT', 'OTHER', name='filecategory', create_type=False), nullable=True, server_default='OTHER'),
        sa.Column('message_id', sa.Integer(), nullable=True),
        sa.Column('job_id', sa.Integer(), nullable=True),
        sa.Column('contract_id', sa.Integer(), nullable=True),
        sa.Column('width', sa.Integer(), nullable=True),
        sa.Column('height', sa.Integer(), nullable=True),
        sa.Column('cloud_metadata', sa.JSON(), nullable=True),
        sa.Column('is_deleted', sa.Boolean(), nullable=True, server_default='false'),
        sa.Column('deleted_at', sa.DateTime(), nullable=True),
        sa.Column('created_at', sa.DateTime(), nullable=True, server_default=sa.text('CURRENT_TIMESTAMP')),
        sa.Column('updated_at', sa.DateTime(), nullable=True, server_default=sa.text('CURRENT_TIMESTAMP')),
        sa.ForeignKeyConstraint(['contract_id'], ['contracts.id'], ),
        sa.ForeignKeyConstraint(['job_id'], ['jobs.id'], ),
        sa.ForeignKeyConstraint(['message_id'], ['messages.id'], ),
        sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
        sa.PrimaryKeyConstraint('id')
    )
    
    # Create indexes
    op.create_index('idx_file_user_category', 'file_uploads', ['user_id', 'category'])
    op.create_index('idx_file_message', 'file_uploads', ['message_id'])
    op.create_index('idx_file_job', 'file_uploads', ['job_id'])
    op.create_index('idx_file_contract', 'file_uploads', ['contract_id'])
    op.create_index('idx_file_storage', 'file_uploads', ['storage_backend'])


def downgrade():
    # Drop table and indexes
    op.drop_index('idx_file_storage', table_name='file_uploads')
    op.drop_index('idx_file_contract', table_name='file_uploads')
    op.drop_index('idx_file_job', table_name='file_uploads')
    op.drop_index('idx_file_message', table_name='file_uploads')
    op.drop_index('idx_file_user_category', table_name='file_uploads')
    op.drop_table('file_uploads')
    
    # Drop enum types
    sa.Enum(name='filecategory').drop(op.get_bind(), checkfirst=True)
    sa.Enum(name='storagebackend').drop(op.get_bind(), checkfirst=True)
