<?php

namespace GriffinForms\Frontend\Html\Security\Captcha;

/**
 * hCaptcha frontend adapter.
 */
class Hcaptcha extends Format
{
    private $token_key = 'hcaptcha';
    private $log;

    public function isEnabled(): bool
    {
        return !empty($this->options['enable_hcaptcha']);
    }

    public function renderField(string $position): string
    {
        if (!$this->isEnabled()) {
            return '';
        }

        $html  = '<div class="griffinform-hcaptcha-container d-flex justify-content-center">';
        $html .= '<div class="h-captcha" data-sitekey="' . esc_attr($this->options['hcaptcha_site_key'] ?? '') . '"></div>';
        $html .= '</div>';
        return $html;
    }

    public function enqueueScripts(): void
    {
        if (!$this->isEnabled()) {
            return;
        }

        wp_enqueue_script('griffinforms-hcaptcha', 'https://js.hcaptcha.com/1/api.js', [], null, true);
    }

    public function getTokenKey(): string
    {
        return $this->token_key;
    }

    public function getClientContext(): array
    {
        return [
            'enabled'  => $this->isEnabled(),
            'id'       => 'hcaptcha',
            'token_key'=> $this->token_key,
            'site_key' => $this->options['hcaptcha_site_key'] ?? '',
        ];
    }

    public function validateSubmission($antispam_data, array $form_data): array
    {
        $this->initializeLogger();
        $token = $antispam_data->{$this->token_key} ?? '';
        if (empty($token)) {
            $this->logEvent('warning', 'hCaptcha token missing during validation.');
            return ['success' => false, 'message' => __('Unable to submit. hCaptcha token missing.', 'griffinforms-form-builder')];
        }

        $secret = $this->options['hcaptcha_secret_key'] ?? '';
        if (empty($secret)) {
            $this->logEvent('error', 'hCaptcha secret key missing during validation.');
            return ['success' => false, 'message' => __('hCaptcha secret key missing.', 'griffinforms-form-builder')];
        }

        $response = wp_remote_post('https://hcaptcha.com/siteverify', [
            'timeout' => 10,
            'body'    => [
                'secret'   => $secret,
                'response' => $token,
            ],
        ]);

        if (is_wp_error($response)) {
            $this->logEvent('error', 'Unable to reach hCaptcha endpoint.', ['error' => $response->get_error_message()]);
            return ['success' => false, 'message' => sprintf(__('Unable to reach hCaptcha: %s', 'griffinforms-form-builder'), $response->get_error_message())];
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (!is_array($body) || !($body['success'] ?? false)) {
            $error_codes = isset($body['error-codes']) ? (array) $body['error-codes'] : [];
            $this->logEvent('warning', 'hCaptcha assessment failed.', ['codes' => $error_codes, 'body' => $body]);
            return ['success' => false, 'message' => $this->resolveFriendlyMessage($error_codes)];
        }

        $this->logEvent('info', 'hCaptcha validation succeeded.');
        return ['success' => true];
    }

    private function initializeLogger(): void
    {
        if ($this->log) {
            return;
        }

        if (class_exists('\GriffinForms\Log')) {
            $this->log = \GriffinForms\Log::getInstance();
        }
    }

    private function logEvent(string $level, string $message, array $context = []): void
    {
        if (!$this->log) {
            return;
        }

        $log_message = $message;
        if (!empty($context)) {
            $log_message .= ' Context: ' . wp_json_encode($context);
        }

        $this->log->add(
            $level,
            'form',
            (int) $this->form_id,
            get_current_user_id(),
            $log_message,
            'Integration (hcaptcha)'
        );
    }

    private function resolveFriendlyMessage(array $codes): string
    {
        if (empty($codes)) {
            return __('Unable to submit. hCaptcha assessment failed. Please refresh and try again.', 'griffinforms-form-builder');
        }

        $map = [
            'missing-input-secret'       => __('Cannot validate hCaptcha because the secret key is missing.', 'griffinforms-form-builder'),
            'invalid-input-secret'       => __('Your hCaptcha secret key looks incorrect. Please double-check it in the integration settings.', 'griffinforms-form-builder'),
            'missing-input-response'     => __('Please complete the hCaptcha challenge before submitting.', 'griffinforms-form-builder'),
            'invalid-input-response'     => __('hCaptcha could not verify this challenge response. Please try again.', 'griffinforms-form-builder'),
            'bad-request'                => __('hCaptcha returned a bad request. Please refresh the page and try again.', 'griffinforms-form-builder'),
            'not-using-dummy-passcode'   => __('hCaptcha test mode requires the dummy passcode. Update your configuration or disable test mode.', 'griffinforms-form-builder'),
            'invalid-or-already-seen-response' => __('This hCaptcha verification has already been used. Please complete the challenge again.', 'griffinforms-form-builder'),
        ];

        foreach ($codes as $code) {
            if (isset($map[$code])) {
                return $map[$code];
            }
        }

        return __('Unable to submit. hCaptcha assessment failed. Please refresh and try again.', 'griffinforms-form-builder');
    }
}
