import time
import random
import asyncio
from typing import Callable

class EntropyScheduler:
    def __init__(self, base_interval: float = 30.0):
        self.base_interval = base_interval
        self.phase_offset = 0.0
        self.drift_sigma = 5.0
        
    def next_execution_time(self) -> float:
        """
        Calculate next execution with drift and phase rotation.
        """
        # Base interval with Gaussian noise
        noisy_interval = self.base_interval + random.gauss(0, self.drift_sigma)
        
        # Phase shift accumulation (simulates human circadian variance)
        self.phase_offset += random.uniform(-0.5, 0.5)
        
        # Clamp to reasonable bounds to prevent zero or negative
        next_time = max(5.0, noisy_interval + self.phase_offset)
        
        return time.time() + next_time
    
    async def dispatch_with_entropy(self, task: Callable):
        """
        Execute task at entropic time with pre-task jitter.
        """
        execution_time = self.next_execution_time()
        delay = execution_time - time.time()
        if delay > 0:
            await asyncio.sleep(delay)
        
        # Pre-execution jitter (simulate human hesitation)
        await asyncio.sleep(random.uniform(0.1, 0.8))
        
        # Execute the task
        if asyncio.iscoroutinefunction(task):
            await task()
        elif asyncio.iscoroutine(task):
             await task
        else:
            task()
