import sys
from pathlib import Path
from random import random, randint, choice
from typing import List

# Add framework root and src to path for imports
framework_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(framework_root))
sys.path.insert(0, str(framework_root / "src"))

from demos.school_demo.src.collectives import Neighborhood
from demos.school_demo.src.networks import FriendshipManager
from demos.school_demo.src.schoolServices import DisciplineService, CounselingService, HousingService
from demos.school_demo.src.schoolSchedule import SchoolSchedule
from demos.school_demo.src.schoolSingleRunner import SchoolSingleRunner
from demos.school_demo.src.schoolpopulation import SchoolPopulation
from layer1_core.managers.population import Population
from layer2_simulation.world_builder import WorldBuilder


class SchoolWorld(WorldBuilder):
    """World builder for the school simulation.

    This class sets up all services and delegates behavior to them.
    Services handle all scheduling and agent interactions.
    """

    def __init__(self, param_dict) -> None:
        # Initialize parent class first to set up ServiceRegistry
        super().__init__(param_dict)

        self.params = param_dict
        self.schedule = SchoolSchedule()

        # Create and register all services (passing param_dict to each)
        self.friendshipManager = FriendshipManager("friendship_manager", param_dict)
        self.services.register(self.friendshipManager)
        self.friendshipManager.register_world(self)

        self.disciplineService = DisciplineService("discipline_service", param_dict)
        self.services.register(self.disciplineService)
        self.disciplineService.register_world(self)

        self.counselingService = CounselingService("counseling_service", param_dict)
        self.services.register(self.counselingService)
        self.counselingService.register_world(self)

        self.housingService = HousingService("housing_service", param_dict)
        self.services.register(self.housingService)
        self.housingService.register_world(self)

        # Create neighborhoods and population
        self.neighborhoods = self.make_neighborhoods(count=param_dict.get('neighborhood_count', 3))
        self.population = SchoolPopulation(param_dict, self.neighborhoods)

        # Use services to set up initial state
        self.friendshipManager.make_random_friendships(self.population, count=50)


    def make_neighborhoods(self, count: int = 1) -> List[Neighborhood]:
        """Create neighborhoods for the simulation.

        Args:
            count: Number of neighborhoods to create

        Returns:
            List of Neighborhood instances
        """
        neighborhoods = []

        for i in range(count):
            this_neighborhood = Neighborhood(
                collective_id=f"neighborhood_{i}",
                segregation_metric=0.1,
                eviction_rate=0.1,
                housing_security=0.1,
                vacant_unit_percent=0.01,
                alcohol_tabac_biz_percent=0.005,
                fringe_bank_biz_percent=0.01
            )
            neighborhoods.append(this_neighborhood)
        return neighborhoods

    def setup_events(self):
        """Set up simulation events by delegating to services.

        Services are responsible for scheduling their own events.
        This ensures all behavior logic stays within services.
        """
        # Define simulation time range
        start_step = 1
        end_step = 1001

        # Have each service schedule its own events
        self.disciplineService.schedule_behavior_evaluations(
            schedule=self.schedule,
            students=self.population.students,
            teachers=self.population.teachers,
            start_step=start_step,
            end_step=end_step
        )

        self.friendshipManager.schedule_friendship_interactions(
            schedule=self.schedule,
            start_step=start_step,
            end_step=end_step
        )

        # Could add more service-scheduled events here:
        # self.housingService.schedule_housing_evaluations(...)
        # self.counselingService.schedule_counseling_sessions(...)
