<?php

namespace GriffinForms\Includes\Integrations\Paypal;

/**
 * PayPal payment integration.
 */
class Main extends \GriffinForms\Includes\Integrations\Format
{
    protected function setMeta()
    {
        $this->meta = 'paypal';
        $this->id = 'paypal';
    }

    protected function buildInfo(): array
    {
        return [
            'id'       => 'paypal',
            'name'     => 'PayPal',
            'category' => 'Payments',
        ];
    }

    public function getStatus(): array
    {
        $configured = $this->isConfigured();

        return [
            'configured' => $configured,
            'active'     => $configured,
            'message'    => $configured ? 'Configured' : 'Not configured',
        ];
    }

    public function getConfigFields(): array
    {
        return [
            ['name' => 'paypal_mode', 'label' => 'Mode', 'type' => 'select', 'required' => true],
            ['name' => 'paypal_client_id', 'label' => 'Client ID', 'type' => 'text', 'required' => true],
            ['name' => 'paypal_client_secret', 'label' => 'Client Secret', 'type' => 'password', 'required' => true],
        ];
    }

    protected function validateConnection(): array
    {
        $client_id = $this->getOption('client_id');
        $client_secret = $this->getOption('client_secret');
        $mode = $this->getMode();
        $form_id = $this->resolveFormContextId();

        if ($client_id === '' || $client_secret === '') {
            return [
                'success' => false,
                'message' => __('PayPal client ID and client secret are required.', 'griffinforms-form-builder'),
            ];
        }

        $response = wp_remote_post($this->getApiBaseUrl($mode) . '/v1/oauth2/token', [
            'timeout' => 20,
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($client_id . ':' . $client_secret),
                'Content-Type'  => 'application/x-www-form-urlencoded',
                'Accept'        => 'application/json',
            ],
            'body' => [
                'grant_type' => 'client_credentials',
            ],
        ]);

        if (is_wp_error($response)) {
            $message = 'PayPal connection test failed: ' . $response->get_error_message();
            $this->log->add('error', 'form', $form_id, get_current_user_id(), $message, 'Integration (paypal)');
            return [
                'success' => false,
                'message' => __('Unable to reach PayPal. Please check your credentials and network connectivity.', 'griffinforms-form-builder'),
            ];
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $body = json_decode((string) wp_remote_retrieve_body($response), true);
        if ($code >= 200 && $code < 300 && !empty($body['access_token'])) {
            $this->log->add('success', 'form', $form_id, get_current_user_id(), 'PayPal connection test successful.', 'Integration (paypal)');
            return [
                'success' => true,
                'message' => __('PayPal is properly configured and working correctly.', 'griffinforms-form-builder'),
            ];
        }

        $error_desc = sanitize_text_field($body['error_description'] ?? $body['error'] ?? 'unknown_error');
        $this->log->add(
            'error',
            'form',
            $form_id,
            get_current_user_id(),
            'PayPal connection test failed: ' . $error_desc,
            'Integration (paypal)'
        );

        return [
            'success' => false,
            'message' => __('Unable to validate PayPal credentials. Please verify your mode, client ID, and client secret.', 'griffinforms-form-builder'),
        ];
    }

    public function isLibraryInstalled(): bool
    {
        return true;
    }

    public function getLibraryInstructions(): string
    {
        return '';
    }

    public function isConfigured(): bool
    {
        return $this->getOption('client_id', '') !== '' && $this->getOption('client_secret', '') !== '';
    }

    public function getConfigurationFormHtml(): string
    {
        $mode = $this->getMode();
        $client_id = $this->getOption('client_id', '');
        $client_secret = $this->getOption('client_secret', '');
        $frontend_label = $this->getOption('frontend_label', '');
        $frontend_description = $this->getOption('frontend_description', '');
        $hide_logo = (bool) $this->settings->getOption('paypal_frontend_hide_logo', false);

        $factory = new \GriffinForms\Includes\Integrations\FormControls\Factory();
        $fields_html = '';

        $fields_html .= $factory->create(
            'select',
            'paypal_mode',
            $mode,
            'paypal',
            [
                'label' => __('Mode', 'griffinforms-form-builder'),
                'required' => true,
                'options' => [
                    'sandbox' => __('Sandbox', 'griffinforms-form-builder'),
                    'live' => __('Live', 'griffinforms-form-builder'),
                ],
                'description' => __('Use Sandbox for testing and Live for production transactions.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory->create(
            'text',
            'paypal_client_id',
            $client_id,
            'paypal',
            [
                'label' => __('Client ID', 'griffinforms-form-builder'),
                'type' => 'text',
                'required' => true,
                'description' => __('Your PayPal REST app client ID from the PayPal developer dashboard.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory->create(
            'password',
            'paypal_client_secret',
            $client_secret,
            'paypal',
            [
                'label' => __('Client Secret', 'griffinforms-form-builder'),
                'type' => 'password',
                'required' => true,
                'description' => __('Keep this client secret private. It is used only for server-side OAuth and order capture.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory->create(
            'text',
            'paypal_frontend_label',
            $frontend_label,
            'paypal',
            [
                'label' => __('Frontend Label', 'griffinforms-form-builder'),
                'type' => 'text',
                'required' => false,
                'description' => __('Optional: Overrides the label shown to users (defaults to "PayPal").', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory->create(
            'textarea',
            'paypal_frontend_description',
            $frontend_description,
            'paypal',
            [
                'label' => __('Frontend Description', 'griffinforms-form-builder'),
                'required' => false,
                'description' => __('Optional: Custom description shown under the PayPal label on the payment selector.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory->create(
            'checkbox',
            'paypal_frontend_hide_logo',
            $hide_logo ? '1' : '',
            'paypal',
            [
                'label' => __('Hide Provider Logo', 'griffinforms-form-builder'),
                'description' => __('Enable to hide the PayPal logo on the payment selector.', 'griffinforms-form-builder'),
            ]
        )->render();

        return $this->renderConfigurationFormTemplate('gf-paypal-config-form', 'paypal', $fields_html);
    }

    public function getConfigurationJs(): string
    {
        $id = 'paypal';

        return "
        (function() {
            const form = document.getElementById('gf-paypal-config-form');
            if (!form) return;

            const cancelBtn = form.querySelector('.gf-integration-btn-cancel');
            if (cancelBtn) {
                cancelBtn.addEventListener('click', function(e) {
                    e.preventDefault();
                    window.loadIntegrationInfo('{$id}');
                });
            }

            form.addEventListener('submit', function(e) {
                e.preventDefault();

                const formId = window.griffinformsResolveActiveFormId ? window.griffinformsResolveActiveFormId() : null;
                const formData = new FormData(form);
                const mode = (formData.get('paypal_mode') || 'sandbox').trim();
                const clientId = (formData.get('paypal_client_id') || '').trim();
                const clientSecret = (formData.get('paypal_client_secret') || '').trim();

                if (!mode || !clientId || !clientSecret) {
                    window.showIntegrationsMessage('danger', '" . esc_js(__('Please fill in all required fields.', 'griffinforms-form-builder')) . "');
                    return;
                }

                jQuery.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        action: 'saveIntegrationConfiguration',
                        integration_id: '{$id}',
                        nonce: window.griffinformsIntegrationsNonce || '',
                        form_id: formId || '',
                        paypal_mode: mode,
                        paypal_client_id: clientId,
                        paypal_client_secret: clientSecret,
                        paypal_frontend_label: formData.get('paypal_frontend_label') || '',
                        paypal_frontend_description: formData.get('paypal_frontend_description') || '',
                        paypal_frontend_hide_logo: formData.get('paypal_frontend_hide_logo') ? 1 : 0
                    },
                    success: function(response) {
                        if (response.success) {
                            window.showIntegrationsMessage('success', response.data.message || '" . esc_js(__('PayPal configuration saved.', 'griffinforms-form-builder')) . "');
                            setTimeout(() => window.loadIntegrationInfo('{$id}'), 500);
                        } else {
                            const msg = (response.data && response.data.msg) ? response.data.msg : '" . esc_js(__('Failed to save configuration', 'griffinforms-form-builder')) . "';
                            window.showIntegrationsMessage('danger', msg);
                        }
                    },
                    error: function() {
                        window.showIntegrationsMessage('danger', '" . esc_js(__('Failed to save configuration', 'griffinforms-form-builder')) . "');
                    }
                });
            });
        })();
        ";
    }

    protected function saveConfiguration(array $config): bool
    {
        try {
            $mode = isset($config['paypal_mode']) ? sanitize_key($config['paypal_mode']) : 'sandbox';
            $client_id = isset($config['paypal_client_id']) ? sanitize_text_field($config['paypal_client_id']) : '';
            $client_secret = isset($config['paypal_client_secret']) ? sanitize_text_field($config['paypal_client_secret']) : '';
            $frontend_label = isset($config['paypal_frontend_label']) ? sanitize_text_field($config['paypal_frontend_label']) : '';
            $frontend_description = isset($config['paypal_frontend_description']) ? sanitize_textarea_field($config['paypal_frontend_description']) : '';
            $frontend_hide_logo = !empty($config['paypal_frontend_hide_logo']);

            if (!in_array($mode, ['sandbox', 'live'], true)) {
                $mode = 'sandbox';
            }

            if ($client_id === '' || $client_secret === '') {
                return false;
            }

            $this->settings->updateOption('paypal_mode', $mode, 'payments');
            $this->settings->updateOption('paypal_client_id', $client_id, 'payments');
            $this->settings->updateOption('paypal_client_secret', $client_secret, 'payments');
            $this->settings->updateOption('paypal_frontend_label', $frontend_label, 'payments');
            $this->settings->updateOption('paypal_frontend_description', $frontend_description, 'payments');
            $this->settings->updateOption('paypal_frontend_hide_logo', $frontend_hide_logo ? '1' : '0', 'payments');

            return true;
        } catch (\Exception $e) {
            $message = 'Failed to save PayPal configuration: ' . $e->getMessage();
            $this->log->add('error', 'integration', 0, get_current_user_id(), $message, 'paypal_config');
            return false;
        }
    }

    protected function onDisable()
    {
    }

    protected function getMode(): string
    {
        $mode = sanitize_key((string) $this->settings->getOption('paypal_mode', 'sandbox'));
        return in_array($mode, ['sandbox', 'live'], true) ? $mode : 'sandbox';
    }

    protected function getApiBaseUrl(string $mode): string
    {
        return $mode === 'live'
            ? 'https://api-m.paypal.com'
            : 'https://api-m.sandbox.paypal.com';
    }
}
