"""Add finished products support

Revision ID: 002
Revises: 001
Create Date: 2025-01-15 10:30:00.000000

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

# revision identifiers, used by Alembic.
revision = '002'
down_revision = '001'
branch_labels = None
depends_on = None


def upgrade() -> None:
    # Create new enum types for finished products
    op.execute("""
        CREATE TYPE producttype AS ENUM (
            'ingredient', 'finished_product'
        );
    """)
    
    op.execute("""
        CREATE TYPE productcategory AS ENUM (
            'bread', 'croissants', 'pastries', 'cakes', 'cookies', 
            'muffins', 'sandwiches', 'seasonal', 'beverages', 'other_products'
        );
    """)

    # Add new columns to ingredients table
    op.add_column('ingredients', sa.Column('product_type', 
        sa.Enum('ingredient', 'finished_product', name='producttype'), 
        nullable=False, server_default='ingredient'))
    
    op.add_column('ingredients', sa.Column('product_category', 
        sa.Enum('bread', 'croissants', 'pastries', 'cakes', 'cookies', 'muffins', 'sandwiches', 'seasonal', 'beverages', 'other_products', name='productcategory'), 
        nullable=True))
    
    # Rename existing category column to ingredient_category
    op.alter_column('ingredients', 'category', new_column_name='ingredient_category')
    
    # Add finished product specific columns
    op.add_column('ingredients', sa.Column('supplier_name', sa.String(200), nullable=True))
    op.add_column('ingredients', sa.Column('display_life_hours', sa.Integer(), nullable=True))
    op.add_column('ingredients', sa.Column('best_before_hours', sa.Integer(), nullable=True))
    op.add_column('ingredients', sa.Column('central_baker_product_code', sa.String(100), nullable=True))
    op.add_column('ingredients', sa.Column('delivery_days', sa.String(20), nullable=True))
    op.add_column('ingredients', sa.Column('minimum_order_quantity', sa.Float(), nullable=True))
    op.add_column('ingredients', sa.Column('pack_size', sa.Integer(), nullable=True))
    op.add_column('ingredients', sa.Column('nutritional_info', postgresql.JSONB(astext_type=sa.Text()), nullable=True))

    # Update existing indexes and create new ones
    op.drop_index('idx_ingredients_category', table_name='ingredients')
    
    # Create new indexes for enhanced functionality
    op.create_index('idx_ingredients_product_type', 'ingredients', ['tenant_id', 'product_type', 'is_active'])
    op.create_index('idx_ingredients_ingredient_category', 'ingredients', ['tenant_id', 'ingredient_category', 'is_active'])
    op.create_index('idx_ingredients_product_category', 'ingredients', ['tenant_id', 'product_category', 'is_active'])
    op.create_index('idx_ingredients_central_baker', 'ingredients', ['tenant_id', 'supplier_name', 'product_type'])


def downgrade() -> None:
    # Drop new indexes
    op.drop_index('idx_ingredients_central_baker', table_name='ingredients')
    op.drop_index('idx_ingredients_product_category', table_name='ingredients')
    op.drop_index('idx_ingredients_ingredient_category', table_name='ingredients')
    op.drop_index('idx_ingredients_product_type', table_name='ingredients')
    
    # Remove finished product specific columns
    op.drop_column('ingredients', 'nutritional_info')
    op.drop_column('ingredients', 'pack_size')
    op.drop_column('ingredients', 'minimum_order_quantity')
    op.drop_column('ingredients', 'delivery_days')
    op.drop_column('ingredients', 'central_baker_product_code')
    op.drop_column('ingredients', 'best_before_hours')
    op.drop_column('ingredients', 'display_life_hours')
    op.drop_column('ingredients', 'supplier_name')
    
    # Remove new columns
    op.drop_column('ingredients', 'product_category')
    op.drop_column('ingredients', 'product_type')
    
    # Rename ingredient_category back to category
    op.alter_column('ingredients', 'ingredient_category', new_column_name='category')
    
    # Recreate original category index
    op.create_index('idx_ingredients_category', 'ingredients', ['tenant_id', 'category', 'is_active'])
    
    # Drop new enum types
    op.execute("DROP TYPE productcategory;")
    op.execute("DROP TYPE producttype;")