<?php

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

trait Niwa_AI_Tools_Email {

    private function validate_send_email_message_action_args( $args ) {
        $to_email = isset( $args['to_email'] ) ? sanitize_email( (string) $args['to_email'] ) : '';
        $subject  = isset( $args['subject'] ) ? trim( (string) $args['subject'] ) : '';
        $body     = isset( $args['body'] ) ? trim( (string) $args['body'] ) : '';

        if ( ! is_email( $to_email ) ) {
            return array(
                'success' => false,
                'error'   => 'Ciljna email adresa nije validna za slanje poruke.',
            );
        }

        if ( '' === $subject ) {
            return array(
                'success' => false,
                'error'   => 'Email subject nedostaje.',
            );
        }

        if ( '' === trim( wp_strip_all_tags( $body ) ) ) {
            return array(
                'success' => false,
                'error'   => 'Email body nedostaje.',
            );
        }

        return array(
            'success' => true,
        );
    }



    private function validate_email_message_trash_action_args( $args ) {
        $uid = isset( $args['uid'] ) ? (int) $args['uid'] : 0;
        if ( $uid < 1 ) {
            return array(
                'success' => false,
                'error'   => 'Email UID nedostaje za premestanje u Trash.',
            );
        }

        return array( 'success' => true );
    }

    private function preview_email_message_trash( $args ) {
        $valid = $this->validate_email_message_trash_action_args( $args );
        if ( empty( $valid['success'] ) ) {
            return $valid;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'    => 'email_message_trash',
                'label'   => 'Premesti inbound email u Trash',
                'summary' => 'Premesti email UID ' . (int) $args['uid'] . ' u Trash folder.',
                'args'    => array(
                    'uid' => (int) $args['uid'],
                ),
            ),
        );
    }

    private function execute_email_message_trash_action( $action ) {
        if ( ! $this->email_service || ! method_exists( $this->email_service, 'move_message_to_trash' ) ) {
            return array(
                'success' => false,
                'error'   => 'Email runtime nije ucitan.',
            );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $uid  = isset( $args['uid'] ) ? (int) $args['uid'] : 0;
        $valid = $this->validate_email_message_trash_action_args( array( 'uid' => $uid ) );
        if ( empty( $valid['success'] ) ) {
            return $valid;
        }

        $result = $this->email_service->move_message_to_trash( $uid );
        if ( empty( $result['success'] ) ) {
            return $result;
        }

        return array(
            'success' => true,
            'executed_actions' => array(
                array(
                    'type' => 'email_message_trash',
                    'uid'  => $uid,
                ),
            ),
        );
    }

    private function validate_send_email_with_exchange_rate_action_args( $args ) {
        $normalized = $this->normalize_dynamic_exchange_email_args( $args );
        return $this->validate_send_email_message_action_args(
            array(
                'to_email' => $normalized['to_email'],
                'subject'  => $normalized['subject'],
                'body'     => $normalized['body'],
            )
        );
    }

    private function validate_send_followup_action_args( $args ) {
        $subject    = isset( $args['subject'] ) ? trim( (string) $args['subject'] ) : '';
        $body       = isset( $args['body'] ) ? trim( (string) $args['body'] ) : '';
        $candidates = isset( $args['candidates'] ) && is_array( $args['candidates'] ) ? $args['candidates'] : array();

        if ( '' === $subject ) {
            return array(
                'success' => false,
                'error'   => 'Follow-up email subject nedostaje.',
            );
        }

        if ( '' === trim( wp_strip_all_tags( $body ) ) ) {
            return array(
                'success' => false,
                'error'   => 'Follow-up email body nedostaje.',
            );
        }

        if ( empty( $candidates ) ) {
            return array(
                'success' => false,
                'error'   => 'Nema lead kandidata za follow-up.',
            );
        }

        foreach ( $candidates as $candidate ) {
            $email = isset( $candidate['email'] ) ? sanitize_email( (string) $candidate['email'] ) : '';
            if ( ! is_email( $email ) ) {
                return array(
                    'success' => false,
                    'error'   => 'Jedan od lead kandidata nema validan email.',
                );
            }
        }

        return array(
            'success' => true,
        );
    }

    private function preview_send_email_message( $args ) {
        if ( ! $this->email_service ) {
            return array(
                'success' => false,
                'error'   => 'Email runtime nije ucitan.',
            );
        }

        $recipient_query = trim( (string) ( isset( $args['recipient_query'] ) ? $args['recipient_query'] : '' ) );
        $to_email        = sanitize_email( (string) ( isset( $args['to_email'] ) ? $args['to_email'] : '' ) );
        $subject         = trim( (string) ( isset( $args['subject'] ) ? $args['subject'] : '' ) );
        $body            = (string) ( isset( $args['body'] ) ? $args['body'] : '' );

        if ( '' === $subject ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi email subject za slanje poruke.',
            );
        }

        if ( '' === trim( wp_strip_all_tags( $body ) ) ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi tekst poruke koji saljem mailom.',
            );
        }

        if ( '' === $recipient_query && ! is_email( $to_email ) ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi email adresa ili prepoznatljiv primalac kome saljem poruku.',
            );
        }

        $resolved = $this->email_service->resolve_recipient( $recipient_query, $to_email, 8 );
        if ( empty( $resolved['success'] ) || empty( $resolved['match']['email'] ) ) {
            return array(
                'success' => false,
                'error'   => 'Ne znam email adresu za "' . ( '' !== $recipient_query ? $recipient_query : $to_email ) . '". Reci mi tacnu email adresu ili dodaj kontakt u known recipients.',
            );
        }

        if ( ! empty( $resolved['matches'][1] ) ) {
            $top_score    = intval( isset( $resolved['matches'][0]['score'] ) ? $resolved['matches'][0]['score'] : 0 );
            $second_score = intval( isset( $resolved['matches'][1]['score'] ) ? $resolved['matches'][1]['score'] : 0 );
            if ( $top_score < 95 && ( $top_score - $second_score ) < 10 ) {
                $labels = array();
                foreach ( array_slice( (array) $resolved['matches'], 0, 3 ) as $match ) {
                    $labels[] = ( isset( $match['label'] ) ? (string) $match['label'] : (string) $match['email'] ) . ' <' . ( isset( $match['email'] ) ? (string) $match['email'] : '' ) . '>';
                }

                return array(
                    'success' => false,
                    'error'   => 'Imam vise mogucih email primalaca za "' . $recipient_query . '": ' . implode( ', ', $labels ) . '. Reci mi tacnu email adresu.',
                );
            }
        }

        $match = $resolved['match'];

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'send_email_message',
                'label'            => 'Posalji email poruku',
                'summary'          => 'Posalji email na "' . ( isset( $match['label'] ) && '' !== (string) $match['label'] ? (string) $match['label'] : (string) $match['email'] ) . '" <' . (string) $match['email'] . '>.',
                'rollback_plan'    => 'Email slanje nema rollback. Ako treba, posalji ispravku ili novi follow-up mail.',
                'rollback_support' => 'none',
                'targets'          => array(
                    array(
                        'email'  => (string) $match['email'],
                        'label'  => isset( $match['label'] ) ? (string) $match['label'] : '',
                        'source' => isset( $match['source'] ) ? (string) $match['source'] : '',
                    ),
                ),
                'args'             => array(
                    'to_email'        => (string) $match['email'],
                    'recipient_label' => isset( $match['label'] ) ? (string) $match['label'] : '',
                    'recipient_source'=> isset( $match['source'] ) ? (string) $match['source'] : '',
                    'subject'         => $subject,
                    'body'            => $body,
                ),
            ),
        );
    }

    private function preview_send_email_with_exchange_rate( $args ) {
        if ( ! $this->email_service ) {
            return array(
                'success' => false,
                'error'   => 'Email runtime nije ucitan.',
            );
        }

        $normalized = $this->normalize_dynamic_exchange_email_args( $args );
        $validation = $this->validate_send_email_with_exchange_rate_action_args( $normalized );
        if ( empty( $validation['success'] ) ) {
            return $validation;
        }

        $recipient_query = $normalized['recipient_query'];
        $to_email        = $normalized['to_email'];
        if ( '' === $recipient_query && ! is_email( $to_email ) ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi email adresa ili prepoznatljiv primalac kome saljem poruku.',
            );
        }

        $resolved = $this->email_service->resolve_recipient( $recipient_query, $to_email, 8 );
        if ( empty( $resolved['success'] ) || empty( $resolved['match']['email'] ) ) {
            return array(
                'success' => false,
                'error'   => 'Ne znam email adresu za "' . ( '' !== $recipient_query ? $recipient_query : $to_email ) . '". Reci mi tacnu email adresu ili dodaj kontakt u known recipients.',
            );
        }

        if ( ! empty( $resolved['matches'][1] ) ) {
            $top_score    = intval( isset( $resolved['matches'][0]['score'] ) ? $resolved['matches'][0]['score'] : 0 );
            $second_score = intval( isset( $resolved['matches'][1]['score'] ) ? $resolved['matches'][1]['score'] : 0 );
            if ( $top_score < 95 && ( $top_score - $second_score ) < 10 ) {
                $labels = array();
                foreach ( array_slice( (array) $resolved['matches'], 0, 3 ) as $match ) {
                    $labels[] = ( isset( $match['label'] ) ? (string) $match['label'] : (string) $match['email'] ) . ' <' . ( isset( $match['email'] ) ? (string) $match['email'] : '' ) . '>';
                }

                return array(
                    'success' => false,
                    'error'   => 'Imam vise mogucih email primalaca za "' . $recipient_query . '": ' . implode( ', ', $labels ) . '. Reci mi tacnu email adresu.',
                );
            }
        }

        $match         = $resolved['match'];
        $currency_code = $this->normalize_exchange_currency_code( $normalized['currency_code'] );

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'send_email_with_exchange_rate',
                'label'            => 'Posalji email sa kursom na dan slanja',
                'summary'          => 'Posalji email na "' . ( isset( $match['label'] ) && '' !== (string) $match['label'] ? (string) $match['label'] : (string) $match['email'] ) . '" <' . (string) $match['email'] . '> i tek pri izvrsenju dodaj NBS srednji kurs za ' . $currency_code . '/RSD.',
                'rollback_plan'    => 'Email slanje nema rollback. Ako treba, posalji ispravku ili novi follow-up mail.',
                'rollback_support' => 'none',
                'targets'          => array(
                    array(
                        'email'         => (string) $match['email'],
                        'label'         => isset( $match['label'] ) ? (string) $match['label'] : '',
                        'source'        => isset( $match['source'] ) ? (string) $match['source'] : '',
                        'currency_code' => $currency_code,
                    ),
                ),
                'args'             => array(
                    'to_email'        => (string) $match['email'],
                    'recipient_label' => isset( $match['label'] ) ? (string) $match['label'] : '',
                    'recipient_source'=> isset( $match['source'] ) ? (string) $match['source'] : '',
                    'subject'         => $normalized['subject'],
                    'body'            => $normalized['body'],
                    'currency_code'   => $currency_code,
                    'rate_date'       => $normalized['rate_date'],
                    'rate_source'     => 'nbs_middle_rate',
                ),
            ),
        );
    }

    private function preview_send_followup_to_captured_leads( $args ) {
        if ( ! $this->email_service ) {
            return array(
                'success' => false,
                'error'   => 'Email runtime nije ucitan.',
            );
        }

        $subject = trim( (string) ( isset( $args['subject'] ) ? $args['subject'] : '' ) );
        $body    = (string) ( isset( $args['body'] ) ? $args['body'] : '' );
        $limit   = isset( $args['limit'] ) ? max( 1, min( 100, intval( $args['limit'] ) ) ) : 20;
        $search  = trim( (string) ( isset( $args['search_query'] ) ? $args['search_query'] : '' ) );
        $days    = isset( $args['days'] ) ? max( 1, min( 365, intval( $args['days'] ) ) ) : 90;

        if ( '' === $subject ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi email subject za lead follow-up.',
            );
        }

        if ( '' === trim( wp_strip_all_tags( $body ) ) ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi email body za lead follow-up.',
            );
        }

        $candidates = $this->email_service->get_followup_candidates( $limit, $search, $days );
        if ( empty( $candidates['success'] ) ) {
            return $candidates;
        }

        $items = isset( $candidates['candidates'] ) && is_array( $candidates['candidates'] ) ? $candidates['candidates'] : array();
        if ( empty( $items ) ) {
            return array(
                'success' => false,
                'error'   => 'Nisam nasla leadove sa email adresom koji jos nisu kupili u zadatom periodu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'send_followup_to_captured_leads',
                'label'            => 'Posalji lead follow-up emailove',
                'summary'          => 'Posalji follow-up email na ' . count( $items ) . ' lead kontakata bez kupovine.',
                'rollback_plan'    => 'Email slanje nema rollback. Ako treba, posalji dodatni ispravni mail.',
                'rollback_support' => 'none',
                'targets'          => array_slice( $items, 0, min( 10, count( $items ) ) ),
                'args'             => array(
                    'subject'    => $subject,
                    'body'       => $body,
                    'candidates' => array_values( $items ),
                    'days'       => $days,
                    'search_query' => $search,
                ),
            ),
        );
    }

    private function execute_send_email_message_action( $action ) {
        if ( ! $this->email_service ) {
            return array( 'success' => false, 'error' => 'Email runtime nije ucitan.' );
        }

        $args    = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $to_email = isset( $args['to_email'] ) ? sanitize_email( (string) $args['to_email'] ) : '';
        $subject  = isset( $args['subject'] ) ? (string) $args['subject'] : '';
        $body     = $this->render_email_template(
            isset( $args['body'] ) ? (string) $args['body'] : '',
            array(
                'name'  => isset( $args['recipient_label'] ) ? (string) $args['recipient_label'] : '',
                'email' => $to_email,
                'phone' => '',
            )
        );
        $result = $this->email_service->send_email( $to_email, $subject, $body );

        if ( empty( $result['success'] ) ) {
            return array(
                'success' => false,
                'error'   => isset( $result['error'] ) ? (string) $result['error'] : 'Email slanje nije uspelo.',
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Email je poslat na ' . $to_email . '.',
            'executed_actions' => array(
                array(
                    'type'     => 'send_email_message',
                    'to_email' => $to_email,
                    'subject'  => $subject,
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    private function execute_send_email_with_exchange_rate_action( $action ) {
        if ( ! $this->email_service ) {
            return array( 'success' => false, 'error' => 'Email runtime nije ucitan.' );
        }

        $args       = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $normalized = $this->normalize_dynamic_exchange_email_args( $args );
        $to_email   = $normalized['to_email'];
        $subject    = $normalized['subject'];
        $currency   = $this->normalize_exchange_currency_code( $normalized['currency_code'] );
        $date       = $this->normalize_exchange_rate_date( $normalized['rate_date'] );

        $rate = $this->fetch_nbs_middle_exchange_rate( $currency, $date );
        if ( empty( $rate['success'] ) ) {
            return array(
                'success' => false,
                'error'   => isset( $rate['error'] ) ? (string) $rate['error'] : 'NBS kurs nije mogao da se ucita.',
            );
        }

        $base_body = $this->render_email_template(
            $normalized['body'],
            array(
                'name'  => isset( $args['recipient_label'] ) ? (string) $args['recipient_label'] : '',
                'email' => $to_email,
                'phone' => '',
            )
        );
        $body      = $this->compose_exchange_rate_email_body( $base_body, $rate );
        $result    = $this->email_service->send_email( $to_email, $subject, $body );

        if ( empty( $result['success'] ) ) {
            return array(
                'success' => false,
                'error'   => isset( $result['error'] ) ? (string) $result['error'] : 'Email slanje nije uspelo.',
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Email sa NBS srednjim kursom je poslat na ' . $to_email . '.',
            'executed_actions' => array(
                array(
                    'type'           => 'send_email_with_exchange_rate',
                    'to_email'       => $to_email,
                    'subject'        => $subject,
                    'currency_code'  => $currency,
                    'rate_date'      => isset( $rate['effective_date'] ) ? (string) $rate['effective_date'] : $date,
                    'middle_rate'    => isset( $rate['rate_display'] ) ? (string) $rate['rate_display'] : '',
                    'source_url'     => isset( $rate['source_url'] ) ? (string) $rate['source_url'] : '',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    private function execute_send_followup_to_captured_leads_action( $action ) {
        if ( ! $this->email_service ) {
            return array( 'success' => false, 'error' => 'Email runtime nije ucitan.' );
        }

        $args       = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $subject_tpl = isset( $args['subject'] ) ? (string) $args['subject'] : '';
        $body_tpl    = isset( $args['body'] ) ? (string) $args['body'] : '';
        $candidates  = isset( $args['candidates'] ) && is_array( $args['candidates'] ) ? array_values( $args['candidates'] ) : array();

        $sent     = array();
        $failures = array();

        foreach ( $candidates as $candidate ) {
            if ( ! is_array( $candidate ) ) {
                continue;
            }

            $email = isset( $candidate['email'] ) ? sanitize_email( (string) $candidate['email'] ) : '';
            if ( ! is_email( $email ) ) {
                $failures[] = 'invalid-email';
                continue;
            }

            $subject = $this->render_email_template( $subject_tpl, $candidate );
            $body    = $this->render_email_template( $body_tpl, $candidate );
            $result  = $this->email_service->send_email( $email, $subject, $body );

            if ( empty( $result['success'] ) ) {
                $failures[] = $email . ': ' . ( isset( $result['error'] ) ? (string) $result['error'] : 'send failed' );
                continue;
            }

            $sent[] = array(
                'email'   => $email,
                'subject' => $subject,
            );
        }

        if ( empty( $sent ) ) {
            return array(
                'success'          => false,
                'error'            => ! empty( $failures ) ? 'Nijedan follow-up mail nije poslat. ' . implode( '; ', array_slice( $failures, 0, 5 ) ) : 'Nijedan follow-up mail nije poslat.',
                'executed_actions' => array(),
                'rollback_entries' => array(),
            );
        }

        if ( ! empty( $failures ) ) {
            return array(
                'success'          => true,
                'summary'          => 'Poslala sam follow-up email na ' . count( $sent ) . ' lead kontakata, ali neki nisu prosli: ' . implode( '; ', array_slice( $failures, 0, 5 ) ),
                'executed_actions' => array(
                    array(
                        'type'     => 'send_followup_to_captured_leads',
                        'sent'     => $sent,
                        'count'    => count( $sent ),
                        'failures' => $failures,
                    ),
                ),
                'rollback_entries' => array(),
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Poslala sam follow-up email na ' . count( $sent ) . ' lead kontakata.',
            'executed_actions' => array(
                array(
                    'type'  => 'send_followup_to_captured_leads',
                    'sent'  => $sent,
                    'count' => count( $sent ),
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    private function render_email_template( $text, $recipient = array() ) {
        $recipient = is_array( $recipient ) ? $recipient : array();
        $site_name = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
        $site_url  = home_url( '/' );
        $name      = isset( $recipient['name'] ) ? trim( (string) $recipient['name'] ) : '';
        if ( '' === $name && isset( $recipient['label'] ) ) {
            $name = trim( (string) $recipient['label'] );
        }

        $replacements = array(
            '{{name}}'       => $name,
            '{{first_name}}' => '' !== $name ? strtok( $name, ' ' ) : '',
            '{{email}}'      => isset( $recipient['email'] ) ? (string) $recipient['email'] : '',
            '{{phone}}'      => isset( $recipient['phone'] ) ? (string) $recipient['phone'] : '',
            '{{site_name}}'  => $site_name,
            '{{site_url}}'   => $site_url,
        );

        return strtr( (string) $text, $replacements );
    }

    private function normalize_dynamic_exchange_email_args( $args ) {
        $args = is_array( $args ) ? $args : array();
        $body = isset( $args['body'] ) ? (string) $args['body'] : ( isset( $args['base_body'] ) ? (string) $args['base_body'] : '' );

        return array(
            'recipient_query' => trim( (string) ( isset( $args['recipient_query'] ) ? $args['recipient_query'] : '' ) ),
            'to_email'        => sanitize_email( (string) ( isset( $args['to_email'] ) ? $args['to_email'] : '' ) ),
            'subject'         => trim( (string) ( isset( $args['subject'] ) ? $args['subject'] : '' ) ),
            'body'            => $body,
            'currency_code'   => $this->normalize_exchange_currency_code( isset( $args['currency_code'] ) ? (string) $args['currency_code'] : 'EUR' ),
            'rate_date'       => isset( $args['rate_date'] ) ? trim( (string) $args['rate_date'] ) : '',
        );
    }

    private function normalize_exchange_currency_code( $currency_code ) {
        $currency_code = strtoupper( preg_replace( '/[^A-Z]/', '', strtoupper( (string) $currency_code ) ) );
        return '' !== $currency_code ? substr( $currency_code, 0, 3 ) : 'EUR';
    }

    private function normalize_exchange_rate_date( $date ) {
        $date = trim( (string) $date );
        if ( '' === $date ) {
            return $this->get_site_local_date();
        }

        $timezone = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( 'UTC' );
        foreach ( array( '!Y-m-d', '!d.m.Y.', '!j.n.Y.', '!d.m.Y', '!j.n.Y' ) as $format ) {
            $parsed = DateTimeImmutable::createFromFormat( $format, $date, $timezone );
            if ( $parsed instanceof DateTimeImmutable ) {
                return $parsed->format( 'Y-m-d' );
            }
        }

        $timestamp = strtotime( $date );
        if ( false !== $timestamp ) {
            return gmdate( 'Y-m-d', $timestamp );
        }

        return $this->get_site_local_date();
    }

    private function get_site_local_date() {
        if ( function_exists( 'wp_date' ) && function_exists( 'wp_timezone' ) ) {
            return wp_date( 'Y-m-d', time(), wp_timezone() );
        }

        return date_i18n( 'Y-m-d' );
    }

    private function fetch_nbs_middle_exchange_rate( $currency_code, $date ) {
        $currency_code = $this->normalize_exchange_currency_code( $currency_code );
        $date          = $this->normalize_exchange_rate_date( $date );
        $timezone      = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( 'UTC' );
        $date_object   = DateTimeImmutable::createFromFormat( '!Y-m-d', $date, $timezone );
        if ( ! $date_object instanceof DateTimeImmutable ) {
            return array( 'success' => false, 'error' => 'Datum za NBS kurs nije validan.' );
        }

        $nbs_date = $date_object->format( 'd.m.Y.' );
        $url      = add_query_arg(
            array(
                'Date'                   => $nbs_date,
                'ExchangeRateListTypeID' => 3,
                'isSearchExecuted'       => 'true',
            ),
            'https://webappcenter.nbs.rs/ExchangeRateWebApp/ExchangeRate/IndexByDate'
        );

        $response = wp_remote_get(
            $url,
            array(
                'timeout'     => 12,
                'redirection' => 3,
                'headers'     => array(
                    'User-Agent' => 'Niwa AI WordPress plugin; NBS exchange-rate lookup',
                ),
            )
        );

        if ( is_wp_error( $response ) ) {
            return array(
                'success' => false,
                'error'   => 'NBS kurs nije dostupan: ' . $response->get_error_message(),
            );
        }

        $status = intval( wp_remote_retrieve_response_code( $response ) );
        $html   = (string) wp_remote_retrieve_body( $response );
        if ( $status < 200 || $status >= 300 || '' === trim( $html ) ) {
            return array(
                'success' => false,
                'error'   => 'NBS kurs nije dostupan. HTTP status: ' . $status,
            );
        }

        $parsed = $this->parse_nbs_middle_exchange_rate_html( $html, $currency_code );
        if ( empty( $parsed['success'] ) ) {
            return $parsed;
        }

        $parsed['requested_date'] = $date;
        $parsed['source_url']     = $url;
        return $parsed;
    }

    private function parse_nbs_middle_exchange_rate_html( $html, $currency_code ) {
        $currency_code = $this->normalize_exchange_currency_code( $currency_code );
        $decoded       = html_entity_decode( (string) $html, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
        $plain         = trim( preg_replace( '/\s+/u', ' ', wp_strip_all_tags( $decoded ) ) );
        $effective     = '';

        if ( preg_match( '/([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4})\./u', $plain, $date_match ) ) {
            $effective = $date_match[1];
        }

        if ( ! preg_match_all( '/<tr\b[^>]*>(.*?)<\/tr>/is', $decoded, $rows ) ) {
            return array( 'success' => false, 'error' => 'NBS odgovor nema tabelu kursne liste.' );
        }

        foreach ( $rows[1] as $row_html ) {
            if ( ! preg_match_all( '/<td\b[^>]*>(.*?)<\/td>/is', $row_html, $cells ) ) {
                continue;
            }

            $values = array();
            foreach ( $cells[1] as $cell ) {
                $values[] = trim( preg_replace( '/\s+/u', ' ', wp_strip_all_tags( html_entity_decode( $cell, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) ) ) );
            }

            if ( count( $values ) < 5 || strtoupper( (string) $values[0] ) !== $currency_code ) {
                continue;
            }

            $unit        = max( 1, intval( $values[3] ) );
            $rate_text   = (string) $values[4];
            $rate_number = $this->parse_nbs_decimal_number( $rate_text );
            if ( $rate_number <= 0 ) {
                return array( 'success' => false, 'error' => 'NBS kurs za ' . $currency_code . ' nije numericki validan.' );
            }

            return array(
                'success'        => true,
                'currency_code'  => $currency_code,
                'unit'           => $unit,
                'rate'           => $rate_number,
                'rate_display'   => $rate_text,
                'effective_date' => $effective,
                'inverse_rate'   => $unit / $rate_number,
            );
        }

        return array( 'success' => false, 'error' => 'NBS srednji kurs za ' . $currency_code . ' nije pronadjen.' );
    }

    private function parse_nbs_decimal_number( $value ) {
        $value = trim( preg_replace( '/\s+/u', '', (string) $value ) );
        if ( false !== strpos( $value, ',' ) ) {
            $value = str_replace( '.', '', $value );
            $value = str_replace( ',', '.', $value );
        }

        return is_numeric( $value ) ? (float) $value : 0.0;
    }

    private function compose_exchange_rate_email_body( $body, $rate ) {
        $rate     = is_array( $rate ) ? $rate : array();
        $currency = isset( $rate['currency_code'] ) ? $this->normalize_exchange_currency_code( $rate['currency_code'] ) : 'EUR';
        $unit     = max( 1, intval( isset( $rate['unit'] ) ? $rate['unit'] : 1 ) );
        $date     = isset( $rate['effective_date'] ) && '' !== (string) $rate['effective_date'] ? (string) $rate['effective_date'] : $this->get_site_local_date();
        $display  = isset( $rate['rate_display'] ) ? (string) $rate['rate_display'] : '';
        $inverse  = isset( $rate['inverse_rate'] ) ? (float) $rate['inverse_rate'] : 0.0;
        $suffix   = 'NBS zvanicni srednji kurs na dan slanja (' . $date . '): ' . $unit . ' ' . $currency . ' = ' . $display . ' RSD; 1 RSD = ' . number_format( $inverse, 6, ',', '.' ) . ' ' . $currency . '. Izvor: Narodna banka Srbije.';
        $body     = rtrim( (string) $body );

        if ( $body !== wp_strip_all_tags( $body ) ) {
            return $body . "\n\n" . '<p>' . esc_html( $suffix ) . '</p>';
        }

        return $body . "\n\n" . $suffix;
    }
}
