<?php

namespace EasyLinkAutomations\Actions\Core;

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

use EasyLinkAutomations\Actions\BaseAction;

/**
 * Action that sends an HTTP webhook request.
 */
final class WebhookAction extends BaseAction
{
    public static function getSlug(): string
    {
        return 'core/webhook';
    }

    public static function getName(): string
    {
        return __('Webhook', 'easylink-automations');
    }

    public static function getDescription(): string
    {
        return __('Send an HTTP request to an external URL', 'easylink-automations');
    }

    public static function getCategory(): string
    {
        return '';
    }

    public static function getIcon(): string
    {
        return 'api';
    }

    public static function getConfigFields(): array
    {
        return [
            'url' => [
                'label'            => 'URL',
                'type'             => 'url',
                'supports_mapping' => true,
                'required'         => true,
                'placeholder'      => 'https://example.com/webhook',
            ],
            'method' => [
                'label'   => 'Method',
                'type'    => 'select',
                'options' => [
                    ['value' => 'POST', 'label' => 'POST'],
                    ['value' => 'GET', 'label' => 'GET'],
                    ['value' => 'PUT', 'label' => 'PUT'],
                    ['value' => 'PATCH', 'label' => 'PATCH'],
                    ['value' => 'DELETE', 'label' => 'DELETE'],
                ],
                'default' => 'POST',
            ],
            'headers' => [
                'label'            => 'Headers (JSON)',
                'type'             => 'textarea',
                'supports_mapping' => true,
                'placeholder'      => '{"Authorization": "Bearer token"}',
            ],
            'body' => [
                'label'            => 'Body (JSON)',
                'type'             => 'textarea',
                'supports_mapping' => true,
                'placeholder'      => '{"title": "{{post_title}}"}',
            ],
            'send_trigger_data' => [
                'label'   => 'Include all trigger data in body',
                'type'    => 'toggle',
                'default' => false,
            ],
        ];
    }

    public function execute(array $triggerData, array $config): array
    {
        $missing = $this->validateRequired($config);
        if ($missing) {
            return [
                'success' => false,
                'message' => 'Missing required fields: ' . implode(', ', $missing),
            ];
        }

        $url    = trim((string) $this->mapValue($config['url'], $triggerData));
        $method = strtoupper((string) ($config['method'] ?? 'POST'));

        if (!preg_match('#^https?://#i', $url)) {
            return [
                'success' => false,
                'message' => 'URL must start with http:// or https://',
            ];
        }

        if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], true)) {
            return [
                'success' => false,
                'message' => 'Invalid HTTP method',
            ];
        }

        $headers = ['Content-Type' => 'application/json'];
        if (!empty($config['headers'])) {
            $mappedHeaders = $this->mapValue($config['headers'], $triggerData);
            $customHeaders = json_decode((string) $mappedHeaders, true);

            if (json_last_error() !== JSON_ERROR_NONE || !is_array($customHeaders)) {
                return [
                    'success' => false,
                    'message' => 'Headers must be a valid JSON object',
                ];
            }

            foreach ($customHeaders as $headerName => $headerValue) {
                if (!is_string($headerName) || $headerName === '' || is_array($headerValue)) {
                    return [
                        'success' => false,
                        'message' => 'Headers must be a valid JSON object',
                    ];
                }
            }

            $headers = array_merge($headers, $customHeaders);
        }

        $body = null;
        if (in_array($method, ['POST', 'PUT', 'PATCH'], true)) {
            if (!empty($config['send_trigger_data'])) {
                $body = $triggerData;
            } elseif (!empty($config['body'])) {
                $mappedBody = $this->mapValue($config['body'], $triggerData);
                $body       = json_decode((string) $mappedBody, true);

                if (json_last_error() !== JSON_ERROR_NONE) {
                    return [
                        'success' => false,
                        'message' => 'Body must be valid JSON',
                    ];
                }
            }
        }

        $args = [
            'method'  => $method,
            'headers' => $headers,
            'timeout' => 30,
        ];

        if ($body !== null) {
            $args['body'] = wp_json_encode($body);
        }

        $response = wp_remote_request($url, $args);

        if (is_wp_error($response)) {
            return [
                'success' => false,
                'message' => 'Request failed: ' . $response->get_error_message(),
            ];
        }

        $statusCode = wp_remote_retrieve_response_code($response);
        $success    = $statusCode >= 200 && $statusCode < 300;

        return [
            'success' => $success,
            'message' => $success ? "Request successful (HTTP {$statusCode})" : "Request failed (HTTP {$statusCode})",
            'data'    => [
                'status_code' => $statusCode,
                'response'    => wp_remote_retrieve_body($response),
            ],
        ];
    }
}
