<?php
/**
 * 247ChatMate — Managed Mail Relay Proof
 * --------------------------------------
 * Lightweight relay proof for client sites that cannot send mail locally.
 *
 * Scope: 247CHATMATEEMAILRELAYPROOF1
 * - Client site saves the lead locally first through the existing fallback layer.
 * - When selected, the client site sends a small signed payload to a 247ChatMate relay endpoint.
 * - Relay site verifies the shared token hash and sends through its own working WordPress/SMTP route.
 * - No AI/token usage, no provider keys exposed to clients, no changes to widget/chips/WhatsApp.
 */

defined('ABSPATH') || exit;

if (!defined('MATEWA_MANAGED_MAIL_RELAY_NAMESPACE')) {
    define('MATEWA_MANAGED_MAIL_RELAY_NAMESPACE', '247chatmate/v1');
}

if (!defined('MATEWA_MANAGED_MAIL_RELAY_ROUTE')) {
    define('MATEWA_MANAGED_MAIL_RELAY_ROUTE', '/mail/relay');
}

if (!defined('MATEWA_MANAGED_MAIL_RELAY_DEFAULT_ENDPOINT')) {
    define('MATEWA_MANAGED_MAIL_RELAY_DEFAULT_ENDPOINT', 'https://247chatmate.com/wp-json/' . MATEWA_MANAGED_MAIL_RELAY_NAMESPACE . MATEWA_MANAGED_MAIL_RELAY_ROUTE);
}

if (!defined('MATEWA_MANAGED_MAIL_RELAY_LAST_OPTION')) {
    define('MATEWA_MANAGED_MAIL_RELAY_LAST_OPTION', 'matewa_managed_mail_relay_last_result');
}

if (!function_exists('matewa_managed_mail_relay_now')) {
    function matewa_managed_mail_relay_now() {
        return current_time('mysql');
    }
}

if (!function_exists('matewa_managed_mail_relay_store_last')) {
    function matewa_managed_mail_relay_store_last(array $result) {
        $safe = array(
            'ok'            => !empty($result['ok']),
            'direction'     => isset($result['direction']) ? sanitize_key((string) $result['direction']) : '',
            'method'        => isset($result['method']) ? sanitize_key((string) $result['method']) : '',
            'error'         => isset($result['error']) ? sanitize_text_field((string) $result['error']) : '',
            'recipient'     => isset($result['recipient']) ? sanitize_email((string) $result['recipient']) : '',
            'endpoint'      => isset($result['endpoint']) ? esc_url_raw((string) $result['endpoint']) : '',
            'response_code' => isset($result['response_code']) ? absint($result['response_code']) : 0,
            'payload_hash'  => isset($result['payload_hash']) ? sanitize_text_field((string) $result['payload_hash']) : '',
            'updated_at'    => matewa_managed_mail_relay_now(),
        );

        update_option(MATEWA_MANAGED_MAIL_RELAY_LAST_OPTION, $safe, false);
        return $safe;
    }
}

if (!function_exists('matewa_managed_mail_relay_get_last')) {
    function matewa_managed_mail_relay_get_last() {
        $last = get_option(MATEWA_MANAGED_MAIL_RELAY_LAST_OPTION, array());
        return is_array($last) ? $last : array();
    }
}

if (!function_exists('matewa_managed_mail_relay_get_token_plain')) {
    function matewa_managed_mail_relay_get_token_plain() {
        if (!function_exists('matewa_client_mail_delivery_get_options') || !function_exists('matewa_client_mail_delivery_decrypt_password')) {
            return '';
        }

        $options = matewa_client_mail_delivery_get_options();
        return matewa_client_mail_delivery_decrypt_password((string) ($options['relay_token_enc'] ?? ''));
    }
}

if (!function_exists('matewa_managed_mail_relay_get_token_hash')) {
    function matewa_managed_mail_relay_get_token_hash() {
        if (!function_exists('matewa_client_mail_delivery_get_options')) {
            return '';
        }

        $options = matewa_client_mail_delivery_get_options();
        return sanitize_text_field((string) ($options['relay_token_hash'] ?? ''));
    }
}

if (!function_exists('matewa_managed_mail_relay_auto_mode_is_allowed')) {
    function matewa_managed_mail_relay_auto_mode_is_allowed() {
        return function_exists('matewa_client_mail_delivery_managed_relay_is_eligible') && matewa_client_mail_delivery_managed_relay_is_eligible();
    }
}

if (!function_exists('matewa_managed_mail_relay_rate_limit_check')) {
    function matewa_managed_mail_relay_rate_limit_check($source_site, $recipient) {
        $source_site = esc_url_raw((string) $source_site);
        $recipient = sanitize_email((string) $recipient);
        $ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field((string) wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
        $key = 'matewa_relay_rate_' . md5($source_site . '|' . $recipient . '|' . $ip);
        $count = absint(get_transient($key));
        if ($count >= 40) {
            return false;
        }

        set_transient($key, $count + 1, HOUR_IN_SECONDS);
        return true;
    }
}

if (!function_exists('matewa_managed_mail_relay_validate_endpoint')) {
    function matewa_managed_mail_relay_validate_endpoint($endpoint) {
        $endpoint = esc_url_raw(trim((string) $endpoint));
        if ('' === $endpoint) {
            return '';
        }

        $parts = wp_parse_url($endpoint);
        if (!is_array($parts) || empty($parts['host']) || strtolower((string) ($parts['scheme'] ?? '')) !== 'https') {
            return '';
        }

        return $endpoint;
    }
}

if (!function_exists('matewa_managed_mail_relay_payload_hash')) {
    function matewa_managed_mail_relay_payload_hash(array $body) {
        return hash('sha256', wp_json_encode($body));
    }
}

if (!function_exists('matewa_managed_mail_relay_send_payload')) {
    function matewa_managed_mail_relay_send_payload(array $payload) {
        if (!function_exists('matewa_client_mail_delivery_get_options')) {
            return array(
                'sent'   => false,
                'method' => 'managed_relay_options_missing',
                'error'  => 'Client mail delivery options are not available.',
            );
        }

        $options = matewa_client_mail_delivery_get_options();
        $endpoint = matewa_managed_mail_relay_validate_endpoint((string) ($options['relay_endpoint'] ?? ''));
        if ('' === $endpoint && defined('MATEWA_MANAGED_MAIL_RELAY_DEFAULT_ENDPOINT')) {
            $endpoint = matewa_managed_mail_relay_validate_endpoint(MATEWA_MANAGED_MAIL_RELAY_DEFAULT_ENDPOINT);
        }
        $token = matewa_managed_mail_relay_get_token_plain();
        $auto_allowed = matewa_managed_mail_relay_auto_mode_is_allowed();

        if ('' === $endpoint) {
            return array(
                'sent'   => false,
                'method' => 'managed_relay_endpoint_missing',
                'error'  => 'Managed relay endpoint is missing.',
            );
        }

        if ('' === $token && !$auto_allowed) {
            return array(
                'sent'   => false,
                'method' => 'managed_relay_not_eligible',
                'error'  => 'Managed relay needs an active trial, licence or agency-managed setup.',
            );
        }

        $safe_payload = array(
            'id'         => sanitize_text_field((string) ($payload['id'] ?? '')),
            'context'    => sanitize_key((string) ($payload['context'] ?? 'lead')),
            'to'         => sanitize_email((string) ($payload['to'] ?? '')),
            'subject'    => sanitize_text_field((string) ($payload['subject'] ?? '')),
            'message'    => wp_kses_post((string) ($payload['message'] ?? '')),
            'headers'    => function_exists('matewa_fallback_mail_normalise_headers') ? matewa_fallback_mail_normalise_headers($payload['headers'] ?? array()) : (array) ($payload['headers'] ?? array()),
            'meta'       => is_array($payload['meta'] ?? null) ? $payload['meta'] : array(),
            'created_at' => sanitize_text_field((string) ($payload['created_at'] ?? matewa_managed_mail_relay_now())),
        );

        if (!is_email($safe_payload['to'])) {
            return array(
                'sent'   => false,
                'method' => 'managed_relay_invalid_recipient',
                'error'  => 'Managed relay recipient email is invalid.',
            );
        }

        $body = array(
            'version'     => '247CHATMATEEMAILRELAYPROOF1',
            'source_site' => esc_url_raw(home_url('/')),
            'sent_at'     => gmdate('c'),
            'payload'     => $safe_payload,
        );
        $payload_hash = matewa_managed_mail_relay_payload_hash($body);
        $body['payload_hash'] = $payload_hash;

        $headers = array(
            'Content-Type'                     => 'application/json; charset=utf-8',
            'X-247ChatMate-Relay-Payload-Hash' => $payload_hash,
            'X-247ChatMate-Relay-Mode'         => '' !== $token ? 'token' : 'entitlement',
        );
        if ('' !== $token) {
            $headers['X-247ChatMate-Relay-Token'] = $token;
        }

        $response = wp_remote_post($endpoint, array(
            'timeout' => 15,
            'headers' => $headers,
            'body' => wp_json_encode($body),
        ));

        if (is_wp_error($response)) {
            $error = $response->get_error_message();
            matewa_managed_mail_relay_store_last(array(
                'ok' => false,
                'direction' => 'outbound',
                'method' => 'managed_relay_http_error',
                'endpoint' => $endpoint,
                'recipient' => $safe_payload['to'],
                'payload_hash' => $payload_hash,
                'error' => $error,
            ));

            return array('sent' => false, 'method' => 'managed_relay_http_error', 'error' => $error);
        }

        $code = absint(wp_remote_retrieve_response_code($response));
        $response_body = json_decode((string) wp_remote_retrieve_body($response), true);
        $response_body = is_array($response_body) ? $response_body : array();
        $ok = (200 <= $code && $code < 300 && !empty($response_body['ok']));
        $error = !$ok ? sanitize_text_field((string) ($response_body['message'] ?? ('Relay returned HTTP ' . $code))) : '';

        matewa_managed_mail_relay_store_last(array(
            'ok' => $ok,
            'direction' => 'outbound',
            'method' => $ok ? 'managed_relay_sent' : 'managed_relay_rejected',
            'endpoint' => $endpoint,
            'recipient' => $safe_payload['to'],
            'response_code' => $code,
            'payload_hash' => $payload_hash,
            'error' => $error,
        ));

        return array(
            'sent'   => $ok,
            'method' => $ok ? 'managed_relay_sent' : 'managed_relay_rejected',
            'error'  => $error,
        );
    }
}

if (!function_exists('matewa_managed_mail_relay_filter_sender')) {
    function matewa_managed_mail_relay_filter_sender($result, $payload) {
        $route = function_exists('matewa_client_mail_delivery_get_route') ? matewa_client_mail_delivery_get_route() : 'site_mail';
        if ('managed_relay' !== $route) {
            return $result;
        }

        return matewa_managed_mail_relay_send_payload(is_array($payload) ? $payload : array());
    }
}
add_filter('matewa_fallback_mail_managed_sender_result', 'matewa_managed_mail_relay_filter_sender', 10, 2);

if (!function_exists('matewa_managed_mail_relay_get_request_header')) {
    function matewa_managed_mail_relay_get_request_header(WP_REST_Request $request, $name) {
        $value = $request->get_header($name);
        return is_array($value) ? reset($value) : (string) $value;
    }
}

if (!function_exists('matewa_managed_mail_relay_prepare_receiver_headers')) {
    function matewa_managed_mail_relay_prepare_receiver_headers(array $headers) {
        $normalised = function_exists('matewa_fallback_mail_normalise_headers') ? matewa_fallback_mail_normalise_headers($headers) : $headers;
        $clean = array();
        $reply_to = '';

        foreach ($normalised as $header) {
            if (0 === stripos((string) $header, 'Reply-To:')) {
                $reply_to = trim(substr((string) $header, 9));
                continue;
            }
            if (0 === stripos((string) $header, 'From:')) {
                continue;
            }
            $clean[] = (string) $header;
        }

        $from_email = function_exists('matewa_fallback_mail_safe_sender_email') ? matewa_fallback_mail_safe_sender_email() : sanitize_email((string) get_option('admin_email', ''));
        if (is_email($from_email)) {
            $clean[] = 'From: 247ChatMate Website Leads <' . $from_email . '>';
        }
        if (is_email($reply_to)) {
            $clean[] = 'Reply-To: ' . sanitize_email($reply_to);
        }

        return array_values(array_unique($clean));
    }
}

if (!function_exists('matewa_managed_mail_relay_rest_callback')) {
    function matewa_managed_mail_relay_rest_callback(WP_REST_Request $request) {
        $expected_hash = matewa_managed_mail_relay_get_token_hash();
        $token = matewa_managed_mail_relay_get_request_header($request, 'x-247chatmate-relay-token');
        $mode = sanitize_key(matewa_managed_mail_relay_get_request_header($request, 'x-247chatmate-relay-mode'));

        $body = $request->get_json_params();
        $body = is_array($body) ? $body : array();
        $payload = isset($body['payload']) && is_array($body['payload']) ? $body['payload'] : array();
        $source_site = isset($body['source_site']) ? esc_url_raw((string) $body['source_site']) : '';

        if ('' !== $expected_hash) {
            if ('' === $token || !hash_equals($expected_hash, hash('sha256', $token))) {
                matewa_managed_mail_relay_store_last(array(
                    'ok' => false,
                    'direction' => 'inbound',
                    'method' => 'managed_relay_auth_failed',
                    'error' => 'Relay token missing or invalid.',
                ));
                return new WP_Error('matewa_relay_forbidden', 'Relay token missing or invalid.', array('status' => 403));
            }
        } elseif ('entitlement' !== $mode || '' === $source_site) {
            matewa_managed_mail_relay_store_last(array(
                'ok' => false,
                'direction' => 'inbound',
                'method' => 'managed_relay_auto_auth_failed',
                'error' => 'Relay request was not recognised as an automatic managed sender request.',
            ));
            return new WP_Error('matewa_relay_forbidden', 'Relay request was not recognised as an automatic managed sender request.', array('status' => 403));
        }

        $to = sanitize_email((string) ($payload['to'] ?? ''));
        if (!is_email($to)) {
            return new WP_Error('matewa_relay_invalid_recipient', 'Relay recipient email is invalid.', array('status' => 400));
        }

        if ('' === $expected_hash && !matewa_managed_mail_relay_rate_limit_check($source_site, $to)) {
            return new WP_Error('matewa_relay_rate_limited', 'Relay rate limit reached for this source site. Try again later.', array('status' => 429));
        }

        $mail_payload = array(
            'id'         => sanitize_text_field((string) ($payload['id'] ?? 'relay_' . wp_generate_uuid4())),
            'context'    => sanitize_key((string) ($payload['context'] ?? 'lead')),
            'to'         => $to,
            'subject'    => sanitize_text_field((string) ($payload['subject'] ?? '247ChatMate lead alert')),
            'message'    => wp_kses_post((string) ($payload['message'] ?? '')),
            'headers'    => matewa_managed_mail_relay_prepare_receiver_headers(is_array($payload['headers'] ?? null) ? $payload['headers'] : array()),
            'meta'       => is_array($payload['meta'] ?? null) ? $payload['meta'] : array(),
            'created_at' => sanitize_text_field((string) ($payload['created_at'] ?? matewa_managed_mail_relay_now())),
            'retries'    => 0,
            'last_error' => '',
        );

        $result = function_exists('matewa_fallback_mail_send_via_site_mail')
            ? matewa_fallback_mail_send_via_site_mail($mail_payload)
            : array('sent' => wp_mail($to, $mail_payload['subject'], $mail_payload['message'], $mail_payload['headers']), 'method' => 'relay_wp_mail', 'error' => '');

        $ok = !empty($result['sent']);
        $payload_hash = isset($body['payload_hash']) ? sanitize_text_field((string) $body['payload_hash']) : '';
        matewa_managed_mail_relay_store_last(array(
            'ok' => $ok,
            'direction' => 'inbound',
            'method' => $ok ? 'relay_site_mail_sent' : 'relay_site_mail_failed',
            'recipient' => $to,
            'payload_hash' => $payload_hash,
            'error' => $ok ? '' : sanitize_text_field((string) ($result['error'] ?? 'Relay mail failed.')),
        ));

        if (!$ok) {
            return new WP_Error('matewa_relay_mail_failed', sanitize_text_field((string) ($result['error'] ?? 'Relay mail failed.')), array('status' => 500));
        }

        return rest_ensure_response(array(
            'ok' => true,
            'method' => 'relay_site_mail_sent',
            'payload_hash' => $payload_hash,
        ));
    }
}

if (!function_exists('matewa_managed_mail_relay_register_rest_route')) {
    function matewa_managed_mail_relay_register_rest_route() {
        register_rest_route(MATEWA_MANAGED_MAIL_RELAY_NAMESPACE, MATEWA_MANAGED_MAIL_RELAY_ROUTE, array(
            'methods'             => 'POST',
            'callback'            => 'matewa_managed_mail_relay_rest_callback',
            'permission_callback' => '__return_true',
        ));
    }
}
add_action('rest_api_init', 'matewa_managed_mail_relay_register_rest_route');
