<?php

namespace EasyLinkAutomations\Actions\Sendy;

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

use EasyLinkAutomations\Actions\BaseAction;

/**
 * Adds a subscriber to a Sendy list.
 */
final class SubscribeAction extends BaseAction
{
    public static function getSlug(): string
    {
        return 'sendy/subscribe';
    }

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

    public static function getDescription(): string
    {
        return __('Add a subscriber to a Sendy list', 'easylink-automations');
    }

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

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

    public static function getRequiresConnection(): ?string
    {
        return 'sendy';
    }

    public static function getConfigFields(): array
    {
        return [
            'brand_id' => [
                'label'         => 'Brand',
                'type'          => 'remote_select',
                'required'      => true,
                'remote_source' => 'sendy/brands',
                'depends_on'    => ['connection_id'],
                'options_key'   => 'brands',
                'note'          => 'Used to look up your lists. Sendy does not receive this value.',
            ],
            'list_id' => [
                'label'         => 'List',
                'type'          => 'remote_select',
                'required'      => true,
                'remote_source' => 'sendy/lists',
                'depends_on'    => ['connection_id', 'brand_id'],
                'options_key'   => 'lists',
            ],
            'email' => [
                'label'            => 'Email',
                'type'             => 'email',
                'required'         => true,
                'placeholder'      => 'subscriber@example.com',
                'supports_mapping' => true,
            ],
            'name' => [
                'label'            => 'Name',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
            ],
            'country' => [
                'label'            => 'Country Code',
                'type'             => 'text',
                'required'         => false,
                'placeholder'      => 'US',
                'note'             => 'Two-letter country code.',
                'supports_mapping' => true,
            ],
            'ipaddress' => [
                'label'            => 'IP Address',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
            ],
            'referrer' => [
                'label'            => 'Referrer URL',
                'type'             => 'text',
                'required'         => false,
                'note'             => 'The URL the subscriber signed up from.',
                'supports_mapping' => true,
            ],
            'gdpr' => [
                'label'    => 'GDPR Consent',
                'type'     => 'toggle',
                'required' => false,
                'note'     => 'Mark the signup as GDPR compliant for EU subscribers.',
            ],
            'silent' => [
                'label'    => 'Skip Double Opt-In',
                'type'     => 'toggle',
                'required' => false,
                'note'     => 'Subscribe immediately even when the list uses double opt-in.',
            ],
        ];
    }

    public function execute(array $triggerData, array $config): array
    {
        $mapped = $this->mapConfig($config, $triggerData);

        $email  = trim((string) ($mapped['email'] ?? ''));
        $listId = trim((string) ($mapped['list_id'] ?? ''));

        $missing = [];
        if ($listId === '') {
            $missing[] = 'List';
        }
        if ($email === '') {
            $missing[] = 'Email';
        }
        if ($missing !== []) {
            return [
                'success' => false,
                'message' => 'Missing required fields after mapping: ' . implode(', ', $missing),
            ];
        }

        if (!is_email($email)) {
            return ['success' => false, 'message' => 'Email must be a valid email address'];
        }

        $body = [
            'email'   => $email,
            'list'    => $listId,
            'boolean' => 'true',
        ];

        foreach (['name', 'country', 'ipaddress', 'referrer'] as $field) {
            $value = trim((string) ($mapped[$field] ?? ''));
            if ($value !== '') {
                $body[$field] = $value;
            }
        }

        foreach (['gdpr', 'silent'] as $flag) {
            if (SendyRequestHelper::toBool($mapped[$flag] ?? false)) {
                $body[$flag] = 'true';
            }
        }

        $response = SendyRequestHelper::post(
            (int) ($config['connection_id'] ?? 0),
            '/subscribe',
            $body
        );

        if (!$response['success']) {
            return ['success' => false, 'message' => $response['message'], 'data' => []];
        }

        $result = $response['body'];

        if (SendyRequestHelper::isAffirmative($result)) {
            return [
                'success' => true,
                'message' => 'Subscriber added to the Sendy list',
                'data'    => ['email' => $email, 'list_id' => $listId],
            ];
        }

        // Sendy reports an existing subscriber as an error, but the intended end
        // state already holds, so re-running an automation should not fail.
        if (strcasecmp(rtrim($result, '.'), 'Already subscribed') === 0) {
            return [
                'success' => true,
                'message' => 'Email is already subscribed to this Sendy list',
                'data'    => ['email' => $email, 'list_id' => $listId, 'already_subscribed' => true],
            ];
        }

        return SendyRequestHelper::failure($result, 'Sendy did not confirm the subscription');
    }
}
