<?php
/**
 * Sends and cleans up Telegram tool-progress status messages.
 *
 * @package Niwa_AI
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Niwa_AI_Admin_Autonomy_Turn_Tool_Status_Messenger {

    private $telegram;
    private $min_visible_seconds;
    private $callbacks;

    public function __construct( $telegram, $min_visible_seconds, $callbacks = array() ) {
        $this->telegram            = $telegram;
        $this->min_visible_seconds = max( 0, intval( $min_visible_seconds ) );
        $this->callbacks           = is_array( $callbacks ) ? $callbacks : array();
    }

    public function maybe_send( $state, $phase, $payload = array() ) {
        if ( ! is_array( $state ) || ! $this->telegram || ! empty( $state['sent_any'] ) ) {
            return is_array( $state ) ? $state : array();
        }
        if ( ! $this->should_show() ) {
            return $state;
        }

        $chat_id    = isset( $state['chat_id'] ) ? trim( (string) $state['chat_id'] ) : '';
        $message_id = isset( $state['message_id'] ) ? intval( $state['message_id'] ) : 0;
        if ( '' === $chat_id ) {
            return $state;
        }

        $tool_name = isset( $payload['tool'] ) ? (string) $payload['tool'] : ( isset( $payload['name'] ) ? (string) $payload['name'] : '' );
        $status    = $this->translate( $chat_id, $tool_name, $phase );
        if ( '' === $status ) {
            return $state;
        }

        $status_key = sanitize_key( (string) $phase . '_' . $tool_name );
        $now        = time();
        $last_at    = intval( isset( $state['last_tool_status_at'] ) ? $state['last_tool_status_at'] : 0 );
        $last_key   = isset( $state['last_tool_status_key'] ) ? (string) $state['last_tool_status_key'] : '';
        $sent_keys  = isset( $state['sent_tool_status_keys'] ) && is_array( $state['sent_tool_status_keys'] )
            ? $state['sent_tool_status_keys']
            : array();
        if ( ! empty( $sent_keys[ $status_key ] ) ) {
            return $state;
        }
        if ( '' !== $last_key && ( $now - $last_at ) < 8 ) {
            return $state;
        }

        $this->log(
            'turn_tool_status_attempt',
            array(
                'chat_id'    => $chat_id,
                'message_id' => $message_id,
                'tool'       => $tool_name,
                'phase'      => $phase,
                'status'     => $status,
                'status_key' => $status_key,
            )
        );

        $sent = $this->telegram->send_message( $chat_id, $status, 0 );
        if ( ! empty( $sent['success'] ) ) {
            $state['last_tool_status_at']   = $now;
            $state['last_tool_status_key']  = $status_key;
            $sent_keys[ $status_key ]       = $now;
            $state['sent_tool_status_keys'] = $sent_keys;

            $message_ids = $this->extract_sent_message_ids( $sent );
            if ( ! empty( $message_ids ) ) {
                $messages = isset( $state['tool_status_messages'] ) && is_array( $state['tool_status_messages'] )
                    ? $state['tool_status_messages']
                    : array();
                $messages[ $status_key ] = array(
                    'tool'        => $tool_name,
                    'phase'       => $phase,
                    'message_ids' => $message_ids,
                    'sent_at'     => $now,
                );
                $state['tool_status_messages'] = $messages;
            }
        }

        $this->log(
            'turn_tool_status_result',
            array(
                'chat_id'     => $chat_id,
                'message_id'  => $message_id,
                'tool'        => $tool_name,
                'phase'       => $phase,
                'send_result' => $sent,
            )
        );

        return $state;
    }

    public function delete( $state, $payload = array(), $reason = 'finished' ) {
        if ( ! is_array( $state ) || ! $this->telegram || ! method_exists( $this->telegram, 'delete_message' ) ) {
            return is_array( $state ) ? $state : array();
        }

        $chat_id = isset( $state['chat_id'] ) ? trim( (string) $state['chat_id'] ) : '';
        if ( '' === $chat_id ) {
            return $state;
        }

        $tool_name  = isset( $payload['tool'] ) ? (string) $payload['tool'] : ( isset( $payload['name'] ) ? (string) $payload['name'] : '' );
        $status_key = sanitize_key( 'start_' . $tool_name );
        if ( '' === $status_key ) {
            return $state;
        }

        $messages = isset( $state['tool_status_messages'] ) && is_array( $state['tool_status_messages'] )
            ? $state['tool_status_messages']
            : array();
        if ( empty( $messages[ $status_key ] ) || ! is_array( $messages[ $status_key ] ) ) {
            return $state;
        }

        $record      = $messages[ $status_key ];
        $message_ids = isset( $record['message_ids'] ) && is_array( $record['message_ids'] )
            ? array_values( array_filter( array_map( 'intval', $record['message_ids'] ) ) )
            : array();
        $visibility = $this->wait_for_minimum_visibility( $record );

        $results = array();
        foreach ( $message_ids as $status_message_id ) {
            $results[] = $this->telegram->delete_message( $chat_id, $status_message_id );
        }

        unset( $messages[ $status_key ] );
        $state['tool_status_messages'] = $messages;

        $this->log(
            'turn_tool_status_delete',
            array(
                'chat_id'            => $chat_id,
                'founder_message_id' => isset( $state['message_id'] ) ? intval( $state['message_id'] ) : 0,
                'tool'               => $tool_name,
                'status_key'         => $status_key,
                'reason'             => sanitize_key( (string) $reason ),
                'message_ids'        => $message_ids,
                'visibility'         => $visibility,
                'results'            => $results,
            )
        );

        return $state;
    }

    public function wait_for_minimum_visibility( $record ) {
        $sent_at     = is_array( $record ) && isset( $record['sent_at'] ) ? intval( $record['sent_at'] ) : 0;
        $visible_for = $sent_at > 0 ? max( 0, time() - $sent_at ) : 0;
        $delay       = ( $sent_at > 0 && $this->min_visible_seconds > 0 ) ? max( 0, $this->min_visible_seconds - $visible_for ) : 0;

        if ( $delay > 0 ) {
            sleep( $delay );
            $visible_for += $delay;
        }

        return array(
            'sent_at'             => $sent_at,
            'min_visible_seconds' => $this->min_visible_seconds,
            'delay_seconds'       => $delay,
            'visible_for_seconds' => $visible_for,
        );
    }

    public function delete_all( $state, $reason = 'turn_ended' ) {
        if ( ! is_array( $state ) || empty( $state['tool_status_messages'] ) || ! is_array( $state['tool_status_messages'] ) ) {
            return is_array( $state ) ? $state : array();
        }

        foreach ( array_keys( $state['tool_status_messages'] ) as $status_key ) {
            $record = isset( $state['tool_status_messages'][ $status_key ] ) && is_array( $state['tool_status_messages'][ $status_key ] )
                ? $state['tool_status_messages'][ $status_key ]
                : array();
            $state = $this->delete(
                $state,
                array(
                    'tool' => isset( $record['tool'] ) ? (string) $record['tool'] : preg_replace( '/^start_/', '', (string) $status_key ),
                ),
                $reason
            );
        }

        return $state;
    }

    public function should_show() {
        if ( ! $this->telegram ) {
            return false;
        }
        if ( method_exists( $this->telegram, 'should_show_tooluse_in_telegram_chat' ) ) {
            return ! empty( $this->telegram->should_show_tooluse_in_telegram_chat() );
        }
        if ( method_exists( $this->telegram, 'get_settings' ) ) {
            $settings = $this->telegram->get_settings();
            return is_array( $settings ) && ! empty( $settings['show_tooluse_in_telegram_chat'] );
        }

        return false;
    }

    private function extract_sent_message_ids( $sent ) {
        if ( ! empty( $sent['message_ids'] ) && is_array( $sent['message_ids'] ) ) {
            return array_values( array_filter( array_map( 'intval', $sent['message_ids'] ) ) );
        }
        if ( ! empty( $sent['message_id'] ) ) {
            return array( intval( $sent['message_id'] ) );
        }
        if ( ! empty( $sent['first_message_id'] ) ) {
            return array( intval( $sent['first_message_id'] ) );
        }

        return array();
    }

    private function translate( $chat_id, $tool_name, $phase ) {
        return (string) $this->call( 'translate', array( $chat_id, $tool_name, $phase ), '' );
    }

    private function log( $event, $context = array() ) {
        $this->call( 'log', array( $event, is_array( $context ) ? $context : array() ), null );
    }

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