<?php
/**
 * Translates runtime tool progress messages for Telegram feedback.
 *
 * @package Niwa_AI
 */

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

class Niwa_AI_Admin_Autonomy_Turn_Tool_Progress_Translator {

    private $locale_ttl;

    public function __construct( $locale_ttl ) {
        $this->locale_ttl = max( 60, intval( $locale_ttl ) );
    }

    public function remember_locale( $message ) {
        if ( ! is_array( $message ) ) {
            return;
        }

        $chat_id = isset( $message['chat_id'] ) ? trim( (string) $message['chat_id'] ) : '';
        $locale  = isset( $message['language_code'] ) ? $this->normalize_locale( $message['language_code'] ) : '';
        if ( '' === $chat_id || '' === $locale ) {
            return;
        }

        if ( ! function_exists( 'update_option' ) || ! function_exists( 'get_option' ) || ! function_exists( 'wp_cache_get' ) || ! function_exists( 'wp_cache_set' ) ) {
            return;
        }

        Niwa_AI_Durable_Cache::set(
            $this->locale_key( $chat_id ),
            $locale,
            $this->locale_ttl
        );
    }

    public function locale_key( $chat_id ) {
        return 'niwa_ai_admin_turn_locale_' . md5( trim( (string) $chat_id ) );
    }

    public function get_locale( $chat_id ) {
        $chat_id = trim( (string) $chat_id );
        $locale  = '';

        if ( '' !== $chat_id && function_exists( 'get_option' ) && function_exists( 'wp_cache_get' ) ) {
            $stored = Niwa_AI_Durable_Cache::get( $this->locale_key( $chat_id ) );
            if ( is_string( $stored ) ) {
                $locale = $this->normalize_locale( $stored );
            }
        }

        if ( '' === $locale && function_exists( 'determine_locale' ) ) {
            $locale = $this->normalize_locale( determine_locale() );
        }

        if ( '' === $locale && function_exists( 'get_locale' ) ) {
            $locale = $this->normalize_locale( get_locale() );
        }

        if ( '' === $locale ) {
            $locale = 'en_US';
        }

        return function_exists( 'apply_filters' )
            ? (string) apply_filters( 'niwa_ai_admin_autonomy_runtime_locale', $locale, $chat_id )
            : $locale;
    }

    public function normalize_locale( $locale ) {
        $locale = trim( str_replace( '-', '_', (string) $locale ) );
        if ( '' === $locale ) {
            return '';
        }

        $parts    = preg_split( '/_+/', $locale );
        $language = isset( $parts[0] ) ? strtolower( preg_replace( '/[^a-z]/i', '', (string) $parts[0] ) ) : '';
        if ( '' === $language ) {
            return '';
        }

        $region = isset( $parts[1] ) ? strtoupper( preg_replace( '/[^a-z]/i', '', (string) $parts[1] ) ) : '';
        if ( '' !== $region ) {
            return $language . '_' . $region;
        }

        $matched = $this->match_locale_by_language( $language );
        return '' !== $matched ? $matched : $language;
    }

    public function match_locale_by_language( $language ) {
        $language = strtolower( preg_replace( '/[^a-z]/i', '', (string) $language ) );
        if ( '' === $language ) {
            return '';
        }

        $candidates = array( 'en_US', 'sr_RS', 'de_DE', 'fr_FR', 'es_ES', 'it_IT', 'pt_BR', 'pt_PT' );
        if ( function_exists( 'determine_locale' ) ) {
            $candidates[] = determine_locale();
        }
        if ( function_exists( 'get_locale' ) ) {
            $candidates[] = get_locale();
        }
        if ( function_exists( 'get_available_languages' ) ) {
            $candidates = array_merge( $candidates, (array) get_available_languages() );
        }

        foreach ( array_unique( array_filter( $candidates ) ) as $candidate ) {
            $candidate = trim( str_replace( '-', '_', (string) $candidate ) );
            if ( '' === $candidate ) {
                continue;
            }

            $parts              = preg_split( '/_+/', $candidate );
            $candidate_language = isset( $parts[0] ) ? strtolower( preg_replace( '/[^a-z]/i', '', (string) $parts[0] ) ) : '';
            $candidate_region   = isset( $parts[1] ) ? strtoupper( preg_replace( '/[^a-z]/i', '', (string) $parts[1] ) ) : '';
            if ( $language === $candidate_language && '' !== $candidate_region ) {
                return $candidate_language . '_' . $candidate_region;
            }
        }

        return '';
    }

    public function translate( $chat_id, $tool_name, $phase = 'start' ) {
        $tool_name = sanitize_key( (string) $tool_name );
        $phase     = sanitize_key( (string) $phase );
        $key       = $this->progress_key( $tool_name, $phase );
        if ( '' === $key ) {
            return '';
        }

        $locale   = $this->get_locale( $chat_id );
        $language = strtolower( substr( $locale, 0, 2 ) );
        $human    = $this->humanize_tool_name( $tool_name );

        $serbian = array(
            'search_code'             => 'Pretrazujem kod (code_search)...',
            'read_file'               => 'Citam fajl (file_read)...',
            'list_files'              => 'Listam fajlove (file_list)...',
            'batch_read'              => 'Citam vise izvora (batch_read)...',
            'inspect_code'            => 'Pregledam kod i fajlove...',
            'technical_context'       => 'Skupljam tehnicki kontekst...',
            'workspace_write'         => 'Upisujem promene u workspace...',
            'coding_shell'            => 'Pokrecem coding shell...',
            'coding_dry_run'          => 'Simuliram izmenu koda...',
            'coding_prepare'          => 'Pripremam coding workspace...',
            'coding_edit'             => 'Menjam workspace kopiju...',
            'coding_diff'             => 'Proveravam diff izmena...',
            'coding_lint'             => 'Proveravam PHP sintaksu...',
            'coding_test'             => 'Pokrecem testove...',
            'coding_apply'            => 'Primenujem proverene izmene...',
            'coding_rollback'         => 'Vracam workspace izmene...',
            'helper_task'             => 'Pustam pomocni task...',
            'session_maintenance'     => 'Sredjujem sesiju pre nastavka...',
            'data_preparation'        => 'Skupljam podatke i pripremam rezultat...',
            'fallback_named_progress' => 'Radim: %s...',
        );

        if ( 'sr' === $language ) {
            return 'fallback_named_progress' === $key
                ? sprintf( $serbian[ $key ], $human )
                : ( isset( $serbian[ $key ] ) ? $serbian[ $key ] : '' );
        }

        $message = $this->run_with_locale(
            $locale,
            function () use ( $key, $human ) {
                $messages = array(
                    'inspect_code'        => __( 'Reviewing code and files...', 'niwa-ai' ),
                    'search_code'         => __( 'Searching code (code_search)...', 'niwa-ai' ),
                    'read_file'           => __( 'Reading file (file_read)...', 'niwa-ai' ),
                    'list_files'          => __( 'Listing files (file_list)...', 'niwa-ai' ),
                    'batch_read'          => __( 'Reading multiple sources (batch_read)...', 'niwa-ai' ),
                    'technical_context'   => __( 'Collecting technical context...', 'niwa-ai' ),
                    'workspace_write'     => __( 'Writing changes to the workspace...', 'niwa-ai' ),
                    'coding_shell'        => __( 'Running coding shell...', 'niwa-ai' ),
                    'coding_dry_run'      => __( 'Simulating code edit...', 'niwa-ai' ),
                    'coding_prepare'      => __( 'Preparing coding workspace...', 'niwa-ai' ),
                    'coding_edit'         => __( 'Editing workspace copy...', 'niwa-ai' ),
                    'coding_diff'         => __( 'Checking edit diff...', 'niwa-ai' ),
                    'coding_lint'         => __( 'Checking PHP syntax...', 'niwa-ai' ),
                    'coding_test'         => __( 'Running tests...', 'niwa-ai' ),
                    'coding_apply'        => __( 'Applying verified edits...', 'niwa-ai' ),
                    'coding_rollback'     => __( 'Rolling back workspace edits...', 'niwa-ai' ),
                    'helper_task'         => __( 'Launching a helper task...', 'niwa-ai' ),
                    'session_maintenance' => __( 'Preparing the session before continuing...', 'niwa-ai' ),
                    'data_preparation'    => __( 'Collecting data and preparing the result...', 'niwa-ai' ),
                );

                return 'fallback_named_progress' === $key
                    ? sprintf( __( 'Working: %s...', 'niwa-ai' ), $human )
                    : ( isset( $messages[ $key ] ) ? $messages[ $key ] : '' );
            }
        );

        if ( function_exists( 'apply_filters' ) ) {
            $message = apply_filters( 'niwa_ai_admin_autonomy_runtime_status_text', $message, $key, $locale, $tool_name, $phase );
        }

        return is_string( $message ) ? $message : '';
    }

    public function progress_key( $tool_name, $phase = 'start' ) {
        $tool_name = sanitize_key( (string) $tool_name );
        if ( 'code_read' === $tool_name ) {
            $tool_name = 'file_read';
        }
        $phase = sanitize_key( (string) $phase );
        if ( '' === $tool_name || 'start' !== $phase ) {
            return '';
        }

        if ( in_array( $tool_name, array( 'tool_search', 'tool_load', 'tool_unload', 'tool_active_list', 'session_status_get', 'founder_notes_get', 'memory_recall_all', 'memory_search', 'memory_get', 'agent_memory_search', 'agent_memory_entry_reader', 'companion_memory_search', 'companion_memory_recall', 'companion_memory_review', 'session_recall' ), true ) ) {
            return '';
        }

        $direct = array(
            'code_search'                => 'search_code',
            'batch_read'                 => 'batch_read',
            'search_text_in_post'        => 'inspect_code',
            'main_coding_shell_run'      => 'coding_shell',
            'main_coding_edit_dry_run'   => 'coding_dry_run',
            'main_coding_workspace_prepare' => 'coding_prepare',
            'main_coding_file_edit'      => 'coding_edit',
            'main_coding_git_diff'       => 'coding_diff',
            'main_coding_lint_check'     => 'coding_lint',
            'main_coding_test_run'       => 'coding_test',
            'main_coding_workspace_apply' => 'coding_apply',
            'main_coding_workspace_rollback' => 'coding_rollback',
        );
        if ( isset( $direct[ $tool_name ] ) ) {
            return $direct[ $tool_name ];
        }

        $groups = array(
            'read_file'           => array( 'file_read', 'skill_file_read' ),
            'list_files'          => array( 'file_list', 'skill_files_list' ),
            'technical_context'   => array( 'code_intelligence_get', 'db_schema_get', 'site_discovery_get', 'workspace_bootstrap_get', 'wp_environment_capabilities_get' ),
            'workspace_write'     => array( 'workspace_bootstrap_write', 'session_note_add' ),
            'helper_task'         => array( 'subagent_spawn', 'sessions_spawn', 'sessions_send', 'coding_workflow_start' ),
            'session_maintenance' => array( 'session_compact', 'session_reset' ),
            'data_preparation'    => array( 'metrics_snapshot', 'frontend_questions_log', 'workspace_export_orders_xlsx', 'read_uploaded_spreadsheet' ),
        );

        foreach ( $groups as $key => $tools ) {
            if ( in_array( $tool_name, $tools, true ) ) {
                return $key;
            }
        }

        return '';
    }

    public function run_with_locale( $locale, $callback ) {
        if ( ! is_callable( $callback ) ) {
            return '';
        }

        $locale   = $this->normalize_locale( $locale );
        $switched = false;

        if (
            '' !== $locale
            && function_exists( 'switch_to_locale' )
            && function_exists( 'restore_previous_locale' )
            && function_exists( 'determine_locale' )
            && determine_locale() !== $locale
        ) {
            $switched = (bool) switch_to_locale( $locale );
        }

        try {
            return call_user_func( $callback );
        } finally {
            if ( $switched ) {
                restore_previous_locale();
            }
        }
    }

    public function humanize_tool_name( $tool_name ) {
        $tool_name = trim( str_replace( '_', ' ', (string) $tool_name ) );
        return '' === $tool_name ? 'alat' : strtolower( $tool_name );
    }
}
