<?php
/**
 * Builds the Telegram/admin status response for the autonomy runtime.
 */

defined( 'ABSPATH' ) || exit;

class Niwa_AI_Admin_Autonomy_Status_Message_Builder {

    private $store;
    private $telegram;
    private $control_plane;
    private $chat_agent;
    private $scheduler;
    private $callbacks;

    public function __construct( $store = null, $telegram = null, $control_plane = null, $chat_agent = null, $scheduler = null, $callbacks = array() ) {
        $this->store         = $store;
        $this->telegram      = $telegram;
        $this->control_plane = $control_plane;
        $this->chat_agent    = $chat_agent;
        $this->scheduler     = $scheduler;
        $this->callbacks     = is_array( $callbacks ) ? $callbacks : array();
    }

    public function build( $context = array() ) {
        $context    = is_array( $context ) ? $context : array();
        $runs       = $this->store && method_exists( $this->store, 'list_recent_runs' ) ? (array) $this->store->list_recent_runs( 3 ) : array();
        $poll_state = $this->telegram && method_exists( $this->telegram, 'get_poll_state' ) ? (array) $this->telegram->get_poll_state() : array();
        $webhook    = $this->telegram && method_exists( $this->telegram, 'get_webhook_state' ) ? (array) $this->telegram->get_webhook_state() : array();
        $runner     = $this->telegram && method_exists( $this->telegram, 'get_runner_state' ) ? (array) $this->telegram->get_runner_state() : array();
        $session_id = isset( $context['session_id'] ) ? (string) $context['session_id'] : '';
        $actor_rows = $this->control_plane && method_exists( $this->control_plane, 'list_sessions_with_pending_actor_messages' )
            ? (array) $this->control_plane->list_sessions_with_pending_actor_messages( 5 )
            : array();

        $lines   = array();
        $lines[] = 'Niwa Admin Autonomy status';
        $lines[] = '';
        $lines[] = 'Transport: telegram webhook' . ( empty( $webhook['active'] ) ? ' (fallback polling)' : '' );
        $lines[] = 'Execution mode: per-session actor runtime';
        $lines[] = 'Last webhook delivery: ' . $this->format_timestamp( isset( $webhook['last_delivery_at'] ) ? $webhook['last_delivery_at'] : 0 );
        $lines[] = 'Last poll: ' . $this->format_timestamp( isset( $poll_state['last_polled_at'] ) ? $poll_state['last_polled_at'] : 0 );
        $lines[] = 'Runner last seen: ' . $this->format_timestamp( isset( $runner['last_seen_at'] ) ? $runner['last_seen_at'] : 0 );
        $lines[] = '';
        $lines[] = 'Pending actor sessions: ' . count( $actor_rows );

        foreach ( $actor_rows as $actor_row ) {
            $actor_row = is_array( $actor_row ) ? $actor_row : array();
            $lines[] = sprintf(
                '- %1$s pending:%2$d active:%3$s',
                isset( $actor_row['session_id'] ) ? (string) $actor_row['session_id'] : '-',
                intval( isset( $actor_row['pending_count'] ) ? $actor_row['pending_count'] : 0 ),
                ! empty( $actor_row['has_active'] ) ? 'yes' : 'no'
            );
        }

        $this->append_chat_agent_sections( $lines, $session_id );
        $this->append_daily_report_section( $lines );
        $this->append_scheduled_jobs_section( $lines );
        $this->append_recent_runs_section( $lines, $runs );

        return implode( "\n", $lines );
    }

    private function append_chat_agent_sections( &$lines, $session_id ) {
        if ( '' !== $session_id && $this->chat_agent ) {
            foreach ( array( 'get_session_status_text', 'get_subagents_status_text' ) as $method ) {
                if ( method_exists( $this->chat_agent, $method ) ) {
                    $text = trim( (string) $this->chat_agent->{$method}( $session_id ) );
                    if ( '' !== $text ) {
                        $lines[] = '';
                        $lines[] = $text;
                    }
                }
            }
        }

        if ( $this->chat_agent && method_exists( $this->chat_agent, 'get_heartbeat_status_text' ) ) {
            $heartbeat_text = trim( (string) $this->chat_agent->get_heartbeat_status_text() );
            if ( '' !== $heartbeat_text ) {
                $lines[] = '';
                $lines[] = $heartbeat_text;
            }
        }
    }

    private function append_daily_report_section( &$lines ) {
        if ( ! $this->chat_agent || ! method_exists( $this->chat_agent, 'get_daily_report_state' ) ) {
            return;
        }

        $report_state = (array) $this->chat_agent->get_daily_report_state();
        if ( empty( $report_state ) ) {
            return;
        }

        $lines[] = '';
        $lines[] = 'Daily report: ' . ( isset( $report_state['last_status'] ) && '' !== (string) $report_state['last_status'] ? (string) $report_state['last_status'] : 'idle' );
        $lines[] = 'Last report sent: ' . $this->format_timestamp( isset( $report_state['last_sent_at'] ) ? $report_state['last_sent_at'] : 0 );
        if ( ! empty( $report_state['last_attempt_at'] ) ) {
            $lines[] = 'Last report attempt: ' . $this->format_timestamp( isset( $report_state['last_attempt_at'] ) ? $report_state['last_attempt_at'] : 0 );
        }
        if ( ! empty( $report_state['last_reason'] ) ) {
            $lines[] = 'Report reason: ' . (string) $report_state['last_reason'];
        }
        if ( ! empty( $report_state['last_summary'] ) ) {
            $lines[] = 'Report summary: ' . $this->truncate_block( (string) $report_state['last_summary'], 220 );
        }
        if ( ! empty( $report_state['last_error'] ) ) {
            $lines[] = 'Report error: ' . $this->truncate_block( (string) $report_state['last_error'], 220 );
        }
    }

    private function append_scheduled_jobs_section( &$lines ) {
        if ( ! $this->scheduler || ! method_exists( $this->scheduler, 'list_jobs' ) ) {
            return;
        }

        $scheduled_jobs = (array) $this->scheduler->list_jobs( '', 'active', 6 );
        $lines[] = '';
        $lines[] = 'Active scheduled jobs: ' . count( $scheduled_jobs );
        foreach ( $scheduled_jobs as $job ) {
            if ( ! is_array( $job ) ) {
                continue;
            }
            $lines[] = sprintf(
                '#%1$d %2$s/%3$s next:%4$s %5$s',
                intval( isset( $job['id'] ) ? $job['id'] : 0 ),
                isset( $job['job_type'] ) ? (string) $job['job_type'] : '-',
                isset( $job['schedule_kind'] ) ? (string) $job['schedule_kind'] : '-',
                isset( $job['next_run_local'] ) && '' !== (string) $job['next_run_local'] ? (string) $job['next_run_local'] : '-',
                isset( $job['title'] ) ? $this->truncate_block( (string) $job['title'], 120 ) : ''
            );
        }
    }

    private function append_recent_runs_section( &$lines, $runs ) {
        if ( empty( $runs ) ) {
            return;
        }

        $lines[] = '';
        $lines[] = 'Poslednji run-ovi:';
        foreach ( $runs as $run ) {
            $run = is_array( $run ) ? $run : array();
            $lines[] = sprintf(
                '#%1$d %2$s/%3$s rollback:%4$s',
                intval( isset( $run['id'] ) ? $run['id'] : 0 ),
                isset( $run['approval_state'] ) ? (string) $run['approval_state'] : 'n/a',
                isset( $run['execution_state'] ) ? (string) $run['execution_state'] : 'n/a',
                isset( $run['rollback_status'] ) ? (string) $run['rollback_status'] : 'n/a'
            );
        }
    }

    private function format_timestamp( $timestamp ) {
        return (string) $this->call( 'format_timestamp', array( $timestamp ), '-' );
    }

    private function truncate_block( $text, $limit ) {
        $truncated = $this->call( 'truncate_text', array( $text, $limit ), null );
        if ( null !== $truncated ) {
            return (string) $truncated;
        }

        $legacy = $this->call( 'truncate_block', array( $text, $limit ), null );
        return null !== $legacy ? (string) $legacy : (string) $text;
    }

    private function call( $name, $args = array(), $default = null ) {
        return Niwa_AI_Admin_Autonomy_Callbacks::call( $this->callbacks, $name, $args, $default );
    }
}
