<?php

namespace EasyLinkAutomations\Actions\CleverReach;

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

use EasyLinkAutomations\Actions\BaseAction;

/**
 * Adds a subscriber to a CleverReach group, updating them when they exist.
 *
 * Uses the upsert endpoint so a repeated form submission refreshes the existing
 * receiver instead of failing, which is the behaviour automations expect.
 *
 * CleverReach REST API v3: POST /v3/groups/{group_id}/receivers/upsert
 */
final class ReceiverUpsertAction extends BaseAction
{
    public static function getSlug(): string
    {
        return 'cleverreach/receiver_upsert';
    }

    public static function getName(): string
    {
        return __('Add or Update Subscriber', 'easylink-automations');
    }

    public static function getDescription(): string
    {
        return __('Add a subscriber to a CleverReach group, or update them if they already exist', 'easylink-automations');
    }

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

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

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

    public static function getConfigFields(): array
    {
        return [
            'group_id' => [
                'label'            => 'Group',
                'type'             => 'remote_select',
                'required'         => true,
                'supports_mapping' => true,
                'placeholder'      => 'Select a CleverReach group...',
                'remote_source'    => 'cleverreach/groups',
                'options_key'      => 'groups',
                'depends_on'       => ['connection_id'],
            ],
            'fields' => [
                'label'            => 'Subscriber Fields',
                'type'             => 'field_mapping',
                'required'         => true,
                'remote_source'    => 'cleverreach/receiver-fields',
                'options_key'      => 'columns',
                'depends_on'       => ['connection_id', 'group_id'],
                'supports_mapping' => true,
            ],
            'source' => [
                'label'            => 'Source',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => 'WordPress contact form',
                'description'      => 'Recorded on the receiver so you can see where the signup came from.',
            ],
            'tags' => [
                'label'            => 'Tags',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => 'newsletter, wordpress',
                'description'      => 'Comma-separated tags. Letters, digits, underscores and hyphens only.',
            ],
            'activate' => [
                'label'       => 'Skip Double Opt-In',
                'type'        => 'toggle',
                'required'    => false,
                'default'     => false,
                'description' => 'Leave this off to add the subscriber as inactive and confirm consent with the '
                    . 'Send Double Opt-In Email action. Turning it on marks the subscriber as already confirmed, '
                    . 'which is only lawful when you hold documented consent.',
            ],
        ];
    }

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

        $connectionId = (int) ($config['connection_id'] ?? 0);

        $split = CleverReachReceiverHelper::splitMapping(
            CleverReachReceiverHelper::decodeMapping($mapped['fields'] ?? [])
        );

        if ($split['email'] === '') {
            return ['success' => false, 'message' => 'Email is required', 'data' => []];
        }
        if (!is_email($split['email'])) {
            return ['success' => false, 'message' => 'Email is not a valid address: ' . $split['email'], 'data' => []];
        }

        $receiver = CleverReachReceiverHelper::buildReceiver($mapped, $split);

        $invalidTags = CleverReachReceiverHelper::invalidTags($receiver['tags'] ?? []);
        if ($invalidTags) {
            return [
                'success' => false,
                'message' => 'Tags may only contain letters, digits, underscores and hyphens: ' . implode(', ', $invalidTags),
                'data'    => [],
            ];
        }

        $groupId = CleverReachRequestHelper::id($mapped['group_id']);

        return CleverReachRequestHelper::request(
            $connectionId,
            'POST',
            '/groups/' . $groupId . '/receivers/upsert',
            ['postdata' => [$receiver]]
        );
    }
}
