# server/init_data.py

from models import (db, 
        User, EnglishRole, PrivateRole, EnglishClass, 
        EnglishLevel, PrivateSchoolClass, PrivateFormStock, PrivateFeeItem,
        PrivateUniform, PrivateFeeAssignment, IslamiyyaFeeSetting
)
from functions import private_school_classes_to_code, get_class_codes_for_group

def create_roles():
    """Create system roles for English and Private School systems"""
    # English system roles
    english_roles = ['Director', 'Cashier', 'Analyst', 'InventoryManager', 'BookSeller']
    for role_name in english_roles:
        if not EnglishRole.query.filter_by(name=role_name).first():
            role = EnglishRole(name=role_name)
            db.session.add(role)
            print(f"Created English role: {role_name}")
    
    # Private school system roles
    private_roles = ['Director', 'Cashier', 'Analyst', 'InventoryManager', 'BookSeller', 'EnrollmentOfficer']
    for role_name in private_roles:
        if not PrivateRole.query.filter_by(name=role_name).first():
            role = PrivateRole(name=role_name)
            db.session.add(role)
            print(f"Created Private role: {role_name}")

def create_english_classes():
    """Create default English classes with their levels"""
    english_classes_data = [
        ('NC', 'Normal Class'),
        ('SP', 'Special Class'),
        ('PS', 'Private Special'),
        ('CTC', 'Children Tutorial Class'),
        ('PT', 'Personal Tutorial'),
        ('CBT', 'Computer Based Test'),
        ('WAEC/NECO', 'WAEC/NECO')
    ]
    
    levels_data = {
        'NC': ['NC 1', 'NC 2', 'NC 3', 'NC Intermediate', 'NC Post-Intermediate', 'NC Advanced'],
        'SP': ['Pre-SP', 'SP 1', 'SP 2', 'SP 3', 'SP Intermediate', 'SP Post-Intermediate', 'SP Advanced'],
        'PS': ['Pre-PS', 'PS 1', 'PS 2', 'PS 3', 'PS Intermediate', 'PS Post-Intermediate', 'PS Advanced'],
        'CTC': ['Pre-CTC', 'CTC 1', 'CTC 2', 'CTC 3', 'CTC 4']
    }
    
    for code, name in english_classes_data:
        english_class = EnglishClass.query.filter_by(code=code).first()
        if not english_class:
            english_class = EnglishClass(name=name, code=code)
            db.session.add(english_class)
            print(f"Created English class: {code} - {name}")
            
            # Add levels for classes that have them
            if code in levels_data:
                for i, level_name in enumerate(levels_data[code], 1):
                    level = EnglishLevel(name=level_name, class_code=code, level_order=i)
                    db.session.add(level)
                    print(f"  Created level {i}: {level_name}")

def create_private_school_classes():
    """Create default private school classes"""
    private_classes = [
        'Pre-Nursery', 'Nursery 1', 'Nursery 2', 'Primary 1', 'Primary 2',
        'Primary 3', 'Primary 4', 'Primary 5', 'JSS 1', 'JSS 2', 'JSS 3',
        'SSS 1', 'SSS 2', 'SSS 3'
    ]
    
    for class_name in private_classes:
        if not PrivateSchoolClass.query.filter_by(name=class_name).first():
            class_code = private_school_classes_to_code[class_name]
            private_class = PrivateSchoolClass(name=class_name, code=class_code)
            db.session.add(private_class)
            print(f"Created private school class: {class_name}")

def create_admin_user():
    """Create default admin user with both English and Private roles"""
    admin = User.query.filter_by(email='admin@school.com').first()
    if not admin:
        admin = User(name='Admin', email='admin@school.com', must_change_password=False)
        admin.set_password('a10249')
        
        # Add Director role for both systems
        english_director = EnglishRole.query.filter_by(name='Director').first()
        private_director = PrivateRole.query.filter_by(name='Director').first()
        
        if english_director:
            admin.english_roles.append(english_director)
        if private_director:
            admin.private_roles.append(private_director)
        
        db.session.add(admin)
        print("Created admin user: admin@school.com / admin123")


def populate_school_fees_and_items():
    """Create form stock, uniforms, and fee items from the breakdown."""

    # ----- Helper to get class codes for a group -----
    def class_codes_for_group(group_name):
        display_names = {
            'Nursery': ['Pre-Nursery', 'Nursery 1', 'Nursery 2'],
            'Primary': ['Primary 1', 'Primary 2', 'Primary 3', 'Primary 4', 'Primary 5'],
            'JSS': ['JSS 1', 'JSS 2', 'JSS 3'],
            'SSS': ['SSS 1', 'SSS 2', 'SSS 3']
        }.get(group_name, [])
        return [private_school_classes_to_code[name] for name in display_names if name in private_school_classes_to_code]

    # ----- 1. Form stock (Admission forms) -----
    form_price = 5000
    for group in ['Nursery', 'Primary', 'JSS', 'SSS']:
        existing = PrivateFormStock.query.filter_by(class_group=group).first()
        if existing:
            print(f"Form stock for {group} already exists, skipping")
            continue

        form = PrivateFormStock(
            class_group=group,
            price=form_price,
            quantity=10
        )
        db.session.add(form)
        db.session.flush()

        fee_item = PrivateFeeItem(
            name=f"Admission Form ({group})",
            amount=form_price,
            termly=False
        )
        db.session.add(fee_item)
        db.session.flush()

        class_codes = class_codes_for_group(group)
        for code in class_codes:
            assignment = PrivateFeeAssignment(fee_item_id=fee_item.id, class_code=code)
            db.session.add(assignment)

        form.fee_item_id = fee_item.id
        print(f"Created form stock and fee item for {group}")

    # ----- 2. Uniform items -----
    uniform_items = [
        ('Uniform (2 sets)', {'Nursery': 29000, 'Primary': 32000, 'JSS': 33000, 'SSS': 34000}, False),
        ('Sweater', {'Nursery': 8000, 'Primary': 8500, 'JSS': 9500, 'SSS': 9500}, False),
        ('Sportswear', {'Nursery': 11500, 'Primary': 11500, 'JSS': 12000, 'SSS': 13000}, False),
        ('Lab Coat', {'SSS': 7000}, False),
    ]

    for title, prices, termly in uniform_items:
        for group, price in prices.items():
            existing_uniform = PrivateUniform.query.filter_by(title=title, class_group=group).first()
            if existing_uniform:
                print(f"Uniform {title} for {group} already exists, skipping")
                continue

            uniform = PrivateUniform(
                title=title,
                price=price,
                quantity=10,
                class_group=group
            )
            db.session.add(uniform)
            db.session.flush()

            fee_item = PrivateFeeItem(
                name=f"{title} ({group})",
                amount=price,
                termly=termly
            )
            db.session.add(fee_item)
            db.session.flush()

            class_codes = class_codes_for_group(group)
            for code in class_codes:
                assignment = PrivateFeeAssignment(fee_item_id=fee_item.id, class_code=code)
                db.session.add(assignment)

            uniform.fee_item_id = fee_item.id
            print(f"Created uniform {title} for {group} (₦{price:,.0f})")

    # ----- 3. Other fee items (tuition, medication, etc.) -----
    fee_data = [
        ('Tuition Fee', True, {'Nursery': 36000, 'Primary': 40000, 'JSS': 52500, 'SSS': 58500}),
        ('Medication', True, {'Nursery': 3000, 'Primary': 3500, 'JSS': 3500, 'SSS': 3500}),
        ('Maintenance', True, {'Nursery': 7000, 'Primary': 7500, 'JSS': 7500, 'SSS': 7500}),
        ('Computer Practical', True, {'SSS': 2000}),
        ('Exam Fee', True, {'Nursery': 8000, 'Primary': 8000, 'JSS': 8500, 'SSS': 8500}),
        ('Utilities', True, {'Nursery': 6000, 'Primary': 6000, 'JSS': 6000, 'SSS': 6000}),
        ('Lab Maintenance', True, {'SSS': 4000}),
        ('Extra Lesson (Compulsory)', True, {'SSS': 5000}),
    ]

    for base_name, termly, group_prices in fee_data:
        for group, amount in group_prices.items():
            full_name = f"{base_name} - {group}"
            existing = PrivateFeeItem.query.filter_by(name=full_name).first()
            if existing:
                print(f"Fee item {full_name} already exists, skipping")
                continue

            fee_item = PrivateFeeItem(
                name=full_name,
                amount=amount,
                termly=termly
            )
            db.session.add(fee_item)
            db.session.flush()

            class_codes = class_codes_for_group(group)
            for code in class_codes:
                assignment = PrivateFeeAssignment(fee_item_id=fee_item.id, class_code=code)
                db.session.add(assignment)

            print(f"Created fee item {full_name} (termly={termly}) for {group}")

    # ----- 4. Single global Acceptance Fee (applies to all classes) -----
    acceptance_fee_name = "Acceptance Fee"
    existing_acceptance = PrivateFeeItem.query.filter_by(name=acceptance_fee_name).first()
    if not existing_acceptance:
        acceptance_fee = PrivateFeeItem(
            name=acceptance_fee_name,
            amount=6000,
            termly=False
        )
        db.session.add(acceptance_fee)
        db.session.flush()

        # Get all class codes from all groups
        all_class_codes = []
        for group in ['Nursery', 'Primary', 'JSS', 'SSS']:
            all_class_codes.extend(class_codes_for_group(group))

        for code in all_class_codes:
            assignment = PrivateFeeAssignment(fee_item_id=acceptance_fee.id, class_code=code)
            db.session.add(assignment)

        print("Created global Acceptance Fee (₦6,000) for all classes")
    else:
        print("Acceptance Fee already exists, skipping")

    setting = IslamiyyaFeeSetting.query.first()
    if not setting:
        setting = IslamiyyaFeeSetting()
        db.session.add(setting)
    setting.form_fee_float = 3000
    setting.term_fee_float = 15000
    
    print("School fees and items population complete.")
    
def initialize_database():
    """Initialize the database with all default data"""
    print("Initializing database...")
    
    # Create all tables
    db.create_all()
    print("Database tables created")
    
    # Create roles for both systems
    create_roles()
    
    # Create English classes and levels
    create_english_classes()
    
    # Create private school classes
    create_private_school_classes()
    
    # Create admin user
    create_admin_user()
    
    populate_school_fees_and_items()
    
    # Commit all changes
    db.session.commit()
    print("Database initialization complete!")