<?php
use boru\ai\Stream\Listener\CompletionStatusListener;
use boru\ai\Stream\Listener\FunctionCallListener;
use boru\ai\Stream\Listener\OutputBufferListener;
use boru\ai\Stream\StreamEventDispatcher;

function attachStreamHandlersToAi($ai) {
    $outputBuffer = new OutputBufferListener();
    $outputBuffer->onDelta(function ($event, $delta) {
        echo $delta;
    });
    $outputBuffer->onDone(function ($event, $text) {
        //echo PHP_EOL . '[text complete]' . PHP_EOL;
    });

    $completionStatus = new CompletionStatusListener();
    $completionStatus->onCompleted(function () {
        echo '[turn status: completed]' . PHP_EOL;
    });
    $completionStatus->onFailed(function () {
        echo '[turn status: failed]' . PHP_EOL;
    });
    $completionStatus->onError(function () {
        echo '[turn status: error]' . PHP_EOL;
    });

    $functionCalls = new FunctionCallListener();
    $functionCalls->onStarted('get_current_temperature', function ($event, $functionName, $arguments) {
        echo PHP_EOL . '[tool started] ' . $functionName . ' ' . json_encode($arguments) . PHP_EOL;
    });
    $functionCalls->onCompleted('*', function ($event, $functionName, $arguments, $output) {
        echo '[tool completed] ' . $functionName . ' => ' . $output . PHP_EOL;
    });
    $functionCalls->onFailed('*', function ($event, $functionName, $arguments, $output) {
        echo '[tool failed] ' . $functionName . ' => ' . $output . PHP_EOL;
    });

    $dispatcher = new StreamEventDispatcher();
    $dispatcher->addListener($outputBuffer);
    $dispatcher->addListener($completionStatus);
    $dispatcher->addListener($functionCalls);
    $ai->eventDispatcher($dispatcher);

    return [$outputBuffer, $completionStatus, $functionCalls];
}