<?php
/**
 * 247ChatMate — Agency Registry Client
 * Checkpoint: AGENCYFREEKEYREGISTRYLOCK1
 *
 * Purpose:
 * - Validate free agency own-site access keys against the 247ChatMate registry.
 * - Keep the client isolated from LemonSqueezy paid licence validation.
 * - Store only safe/masked registry response data locally.
 *
 * Does not:
 * - Grant client seats.
 * - Share an agency master paid LemonSqueezy key with client sites.
 * - Call the registry from frontend/widget requests.
 * - Change widget, chips, WhatsApp handoff, lead emails, weekly summary, Visitor Buttons or sales page behaviour.
 */

defined('ABSPATH') || exit;

if (!defined('MATEWA_AGENCY_REGISTRY_LAST_RESULT_OPTION')) {
    define('MATEWA_AGENCY_REGISTRY_LAST_RESULT_OPTION', 'matewa_agency_registry_last_result');
}

if (!defined('MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION')) {
    define('MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION', 'matewa_agency_registry_last_error');
}

if (!defined('MATEWA_AGENCY_REGISTRY_TIMEOUT')) {
    define('MATEWA_AGENCY_REGISTRY_TIMEOUT', 7);
}

if (!defined('MATEWA_AGENCY_ACCESS_CODE_PREFIX')) {
    define('MATEWA_AGENCY_ACCESS_CODE_PREFIX', 'AGENCY-');
}

if (!function_exists('matewa_agency_registry_get_endpoint')) {
    function matewa_agency_registry_get_endpoint() {
        $endpoint = defined('MATEWA_AGENCY_REGISTRY_ENDPOINT') ? trim((string) MATEWA_AGENCY_REGISTRY_ENDPOINT) : '';
        return esc_url_raw($endpoint);
    }
}

if (!function_exists('matewa_agency_registry_is_configured')) {
    function matewa_agency_registry_is_configured() {
        return '' !== matewa_agency_registry_get_endpoint();
    }
}

if (!function_exists('matewa_agency_registry_sanitise_access_code')) {
    function matewa_agency_registry_sanitise_access_code($code) {
        $code = strtoupper(trim((string) $code));
        $code = preg_replace('/[^A-Z0-9_\-.]/', '', $code);
        return is_string($code) ? $code : '';
    }
}

if (!function_exists('matewa_agency_registry_is_access_code')) {
    function matewa_agency_registry_is_access_code($code) {
        $code = matewa_agency_registry_sanitise_access_code($code);
        if ('' === $code) {
            return false;
        }

        $prefix = defined('MATEWA_AGENCY_ACCESS_CODE_PREFIX') ? strtoupper((string) MATEWA_AGENCY_ACCESS_CODE_PREFIX) : 'AGENCY-';
        return 0 === strpos($code, $prefix);
    }
}

if (!function_exists('matewa_agency_registry_get_saved_access_code')) {
    function matewa_agency_registry_get_saved_access_code() {
        $code = function_exists('matewa_get_license_key') ? matewa_get_license_key() : get_option('matewa_license_key', '');
        $code = matewa_agency_registry_sanitise_access_code($code);
        return matewa_agency_registry_is_access_code($code) ? $code : '';
    }
}

if (!function_exists('matewa_agency_registry_get_site_url')) {
    function matewa_agency_registry_get_site_url() {
        return esc_url_raw(home_url('/'));
    }
}

if (!function_exists('matewa_agency_registry_get_domain')) {
    function matewa_agency_registry_get_domain() {
        $host = wp_parse_url(home_url('/'), PHP_URL_HOST);
        $host = is_string($host) ? strtolower(trim($host)) : '';
        $host = preg_replace('/^www\./', '', $host);
        $host = preg_replace('/[^a-z0-9.-]/', '', $host);
        return is_string($host) ? $host : '';
    }
}

if (!function_exists('matewa_agency_registry_normalise_whatsapp')) {
    function matewa_agency_registry_normalise_whatsapp($number) {
        if (function_exists('matewa_pro_trial_registry_normalise_whatsapp')) {
            return matewa_pro_trial_registry_normalise_whatsapp($number);
        }

        $number = trim((string) $number);
        $number = preg_replace('/[^0-9+]/', '', $number);
        if (!is_string($number) || '' === $number) {
            return '';
        }

        if ('+' === substr($number, 0, 1)) {
            return '+' . preg_replace('/[^0-9]/', '', substr($number, 1));
        }

        return preg_replace('/[^0-9]/', '', $number);
    }
}

if (!function_exists('matewa_agency_registry_get_install_uuid')) {
    function matewa_agency_registry_get_install_uuid() {
        if (function_exists('matewa_pro_trial_registry_get_install_uuid')) {
            return matewa_pro_trial_registry_get_install_uuid();
        }

        if (function_exists('matewa_founder_beta_get_install_uuid')) {
            return matewa_founder_beta_get_install_uuid();
        }

        $option = 'matewa_agency_registry_install_uuid';
        $uuid   = trim((string) get_option($option, ''));

        if ('' !== $uuid) {
            return $uuid;
        }

        $uuid = function_exists('wp_generate_uuid4') ? wp_generate_uuid4() : md5(home_url('/') . microtime(true) . wp_rand());
        update_option($option, $uuid, false);

        return $uuid;
    }
}

if (!function_exists('matewa_agency_registry_get_admin_email_hash')) {
    function matewa_agency_registry_get_admin_email_hash() {
        $email = '';

        if (function_exists('matewa_get_owner_email')) {
            $email = matewa_get_owner_email();
        } else {
            $email = sanitize_email((string) get_option('matewa_marketing_email', ''));
        }

        $email = strtolower(trim((string) $email));

        if ('' === $email || !is_email($email)) {
            return '';
        }

        return hash('sha256', $email);
    }
}

if (!function_exists('matewa_agency_registry_mask_key')) {
    function matewa_agency_registry_mask_key($code) {
        $code = matewa_agency_registry_sanitise_access_code($code);
        $len  = strlen($code);

        if ($len <= 8) {
            return str_repeat('•', $len);
        }

        return substr($code, 0, 6) . str_repeat('•', max(0, $len - 10)) . substr($code, -4);
    }
}

if (!function_exists('matewa_agency_registry_sanitise_result')) {
    function matewa_agency_registry_sanitise_result($result, $access_code = '') {
        if (!is_array($result)) {
            $result = array();
        }

        $client_seats = isset($result['client_seats']) ? max(0, absint($result['client_seats'])) : 0;
        $access_code  = matewa_agency_registry_sanitise_access_code($access_code);

        return array(
            'success'              => !empty($result['success']),
            'ok'                   => !empty($result['ok']) || !empty($result['success']),
            'code'                 => sanitize_key((string) ($result['code'] ?? ($result['message'] ?? 'unknown'))),
            'message'              => sanitize_text_field((string) ($result['message'] ?? '')),
            'status'               => sanitize_key((string) ($result['status'] ?? '')),
            'agency_id'            => sanitize_key((string) ($result['agency_id'] ?? '')),
            'agency_name'          => sanitize_text_field((string) ($result['agency_name'] ?? '')),
            'own_site_access'      => !empty($result['own_site_access']),
            'agency_hub'           => !empty($result['agency_hub']),
            'client_seats'         => $client_seats,
            'seat_source'          => sanitize_key((string) ($result['seat_source'] ?? 'none')),
            'access_start'         => sanitize_text_field((string) ($result['access_start'] ?? '')),
            'access_expiry'        => sanitize_text_field((string) ($result['access_expiry'] ?? '')),
            'revoked'              => !empty($result['revoked']),
            'checked_at'           => time(),
            'endpoint'             => matewa_agency_registry_get_endpoint(),
            'site_url'             => matewa_agency_registry_get_site_url(),
            'domain'               => matewa_agency_registry_get_domain(),
            'install_uuid'         => matewa_agency_registry_get_install_uuid(),
            'masked_key'           => '' !== $access_code ? matewa_agency_registry_mask_key($access_code) : '',
            'activation_code_hash' => '' !== $access_code ? hash('sha256', $access_code . '|' . home_url('/')) : sanitize_text_field((string) ($result['activation_code_hash'] ?? '')),
            'configured'           => matewa_agency_registry_is_configured(),
            'privacy_note'         => 'No IP address, visitor data, lead content, raw admin email, or raw agency key is stored by the plugin-side agency registry client.',
        );
    }
}

if (!function_exists('matewa_agency_registry_store_last_result')) {
    function matewa_agency_registry_store_last_result($result, $access_code = '') {
        $safe = matewa_agency_registry_sanitise_result($result, $access_code);
        update_option(MATEWA_AGENCY_REGISTRY_LAST_RESULT_OPTION, $safe, false);

        if (!empty($safe['success'])) {
            delete_option(MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION);
        } else {
            update_option(MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION, $safe, false);
        }

        return $safe;
    }
}

if (!function_exists('matewa_agency_registry_get_last_result')) {
    function matewa_agency_registry_get_last_result() {
        $stored = get_option(MATEWA_AGENCY_REGISTRY_LAST_RESULT_OPTION, array());
        return is_array($stored) ? $stored : array();
    }
}

if (!function_exists('matewa_agency_registry_get_last_error')) {
    function matewa_agency_registry_get_last_error() {
        $stored = get_option(MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION, array());
        return is_array($stored) ? $stored : array();
    }
}

if (!function_exists('matewa_agency_registry_error')) {
    function matewa_agency_registry_error($code, $message, $access_code = '') {
        return matewa_agency_registry_store_last_result(
            array(
                'success' => false,
                'ok'      => false,
                'code'    => sanitize_key((string) $code),
                'message' => sanitize_text_field((string) $message),
                'status'  => 'unavailable',
            ),
            $access_code
        );
    }
}

if (!function_exists('matewa_agency_registry_build_payload')) {
    function matewa_agency_registry_build_payload($access_code = '') {
        $access_code = matewa_agency_registry_sanitise_access_code($access_code);

        if ('' === $access_code) {
            $access_code = matewa_agency_registry_get_saved_access_code();
        }

        return array(
            'plugin'        => '247chatmate',
            'plugin_version'=> defined('MATEWA_VERSION') ? (string) MATEWA_VERSION : '',
            'site_url'      => matewa_agency_registry_get_site_url(),
            'domain'        => matewa_agency_registry_get_domain(),
            'whatsapp'      => matewa_agency_registry_normalise_whatsapp(get_option('matewa_number', '')),
            'install_uuid'  => matewa_agency_registry_get_install_uuid(),
            'email_hash'    => matewa_agency_registry_get_admin_email_hash(),
            'agency_key'    => $access_code,
            'request_type'  => 'agency_own_site_access',
        );
    }
}

if (!function_exists('matewa_agency_registry_validate_access')) {
    function matewa_agency_registry_validate_access($access_code = '') {
        if (!matewa_agency_registry_is_configured()) {
            return matewa_agency_registry_error(
                'agency_registry_not_configured',
                'Agency access registry is not configured. Admin remains usable; try again after the endpoint is configured.',
                $access_code
            );
        }

        $access_code = matewa_agency_registry_sanitise_access_code($access_code);
        if ('' === $access_code) {
            $access_code = matewa_agency_registry_get_saved_access_code();
        }

        if (!matewa_agency_registry_is_access_code($access_code)) {
            return matewa_agency_registry_error(
                'missing_agency_key',
                'Enter a valid agency own-site access key before refreshing agency access.',
                $access_code
            );
        }

        $payload = matewa_agency_registry_build_payload($access_code);

        if (empty($payload['site_url']) || empty($payload['domain']) || empty($payload['install_uuid'])) {
            return matewa_agency_registry_error(
                'missing_required_fields',
                'This site could not be identified clearly enough to validate agency access.',
                $access_code
            );
        }

        $body = wp_json_encode($payload, JSON_UNESCAPED_SLASHES);
        if (!is_string($body) || '' === $body) {
            return matewa_agency_registry_error(
                'invalid_payload',
                'Agency access validation payload could not be created.',
                $access_code
            );
        }

        $endpoint = matewa_agency_registry_get_endpoint();
        $attempts = array();

        $attempts['json_post'] = wp_remote_post(
            $endpoint,
            array(
                'timeout' => MATEWA_AGENCY_REGISTRY_TIMEOUT,
                'headers' => array(
                    'Accept'       => 'application/json',
                    'Content-Type' => 'application/json; charset=utf-8',
                ),
                'body'    => $body,
            )
        );

        $attempts['form_post'] = wp_remote_post(
            $endpoint,
            array(
                'timeout' => MATEWA_AGENCY_REGISTRY_TIMEOUT,
                'headers' => array(
                    'Accept' => 'application/json',
                ),
                'body'    => $payload,
            )
        );

        $attempts['query_get'] = wp_remote_get(
            add_query_arg($payload, $endpoint),
            array(
                'timeout' => MATEWA_AGENCY_REGISTRY_TIMEOUT,
                'headers' => array(
                    'Accept' => 'application/json',
                ),
            )
        );

        $last_method = '';
        $last_status = 0;
        $last_excerpt = '';
        $last_error_message = '';
        $data = null;

        foreach ($attempts as $method => $attempt_response) {
            $last_method = $method;

            if (is_wp_error($attempt_response)) {
                $last_error_message = $attempt_response->get_error_message();
                continue;
            }

            $last_status = (int) wp_remote_retrieve_response_code($attempt_response);
            $response_body = (string) wp_remote_retrieve_body($attempt_response);
            $last_excerpt = sanitize_text_field(substr(wp_strip_all_tags($response_body), 0, 220));
            $decoded = json_decode($response_body, true);

            if ($last_status >= 200 && $last_status < 300 && is_array($decoded)) {
                $data = $decoded;
                break;
            }
        }

        if (!is_array($data)) {
            if ('' !== $last_error_message && 0 === $last_status) {
                return matewa_agency_registry_error(
                    'agency_registry_unavailable',
                    'Agency access registry could not be reached. Admin remains usable; try again later. ' . $last_error_message,
                    $access_code
                );
            }

            return matewa_agency_registry_store_last_result(
                array(
                    'success'          => false,
                    'ok'               => false,
                    'code'             => 'invalid_agency_registry_response',
                    'message'          => 'Agency access registry returned an invalid response. HTTP ' . $last_status . ' via ' . $last_method . '. Admin remains usable; try again later.',
                    'status'           => 'unavailable',
                    'http_status'      => $last_status,
                    'response_method'  => sanitize_key($last_method),
                    'response_excerpt' => $last_excerpt,
                ),
                $access_code
            );
        }

        $data['success'] = !empty($data['success']) || !empty($data['ok']);
        $data['ok']      = !empty($data['ok']) || !empty($data['success']);
        $data['code']    = sanitize_key((string) ($data['code'] ?? ($data['message'] ?? 'unknown')));
        $data['message'] = sanitize_text_field((string) ($data['message'] ?? ''));
        $data['status']  = sanitize_key((string) ($data['status'] ?? ''));

        return matewa_agency_registry_store_last_result($data, $access_code);
    }
}

if (!function_exists('matewa_clear_agency_registry_validation_state')) {
    function matewa_clear_agency_registry_validation_state($old_access_code = '', $new_access_code = '') {
        $old_access_code = matewa_agency_registry_sanitise_access_code($old_access_code);
        $new_access_code = matewa_agency_registry_sanitise_access_code($new_access_code);

        $old_is_agency = matewa_agency_registry_is_access_code($old_access_code);
        $new_is_agency = matewa_agency_registry_is_access_code($new_access_code);

        if ($new_is_agency && $old_access_code === $new_access_code) {
            return false;
        }

        if (!$old_is_agency && !$new_is_agency) {
            $stored = matewa_agency_registry_get_last_result();
            if (empty($stored)) {
                return false;
            }
        }

        delete_option(MATEWA_AGENCY_REGISTRY_LAST_RESULT_OPTION);
        delete_option(MATEWA_AGENCY_REGISTRY_LAST_ERROR_OPTION);

        return true;
    }
}
