<?php

namespace EasyLinkAutomations\Actions\Mailchimp;

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

use EasyLinkAutomations\Actions\BaseAction;
use EasyLinkAutomations\Models\Connection;

/**
 * Action that updates a member on a Mailchimp list.
 *
 * Migrated from n8n: Mailchimp (resource: member, operation: update)
 * Uses Mailchimp Marketing API v3.0.
 */
final class UpdateMemberAction extends BaseAction
{
    public static function getSlug(): string
    {
        return 'mailchimp/update_member';
    }

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

    public static function getDescription(): string
    {
        return __('Update a subscriber on a Mailchimp audience list', 'easylink-automations');
    }

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

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


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

    public static function getConfigFields(): array
    {
        return [
            'list_id' => [
                'label'         => 'Audience List',
                'type'          => 'remote_select',
                'required'      => true,
                'placeholder'   => 'Select a list...',
                'remote_source' => 'mailchimp/lists',
                'depends_on'    => ['connection_id'],
                'options_key'   => 'lists',
            ],
            'status' => [
                'label'   => 'Status',
                'type'    => 'select',
                'options' => [
                    ['value' => '', 'label' => '— Do not change —'],
                    ['value' => 'subscribed', 'label' => 'Subscribed'],
                    ['value' => 'pending', 'label' => 'Pending'],
                    ['value' => 'unsubscribed', 'label' => 'Unsubscribed'],
                    ['value' => 'cleaned', 'label' => 'Cleaned'],
                    ['value' => 'transactional', 'label' => 'Transactional'],
                ],
                'required' => false,
                'default'  => '',
            ],
            'merge_fields' => [
                'label'            => 'Fields',
                'type'             => 'field_mapping',
                'required'         => true,
                'remote_source'    => 'mailchimp/merge-fields',
                'depends_on'       => ['connection_id', 'list_id'],
                'options_key'      => 'columns',
                'supports_mapping' => true,
            ],
            'language' => [
                'label'       => 'Language',
                'type'        => 'text',
                'required'    => false,
                'placeholder' => 'en',
                'description' => "Subscriber's language code",
            ],
            'vip' => [
                'label'       => 'VIP',
                'type'        => 'toggle',
                'required'    => false,
                'default'     => false,
                'description' => 'VIP status for the subscriber',
            ],
        ];
    }

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

        $connectionId = (int) ($config['connection_id'] ?? 0);
        $token = Connection::getAccessToken($connectionId);
        if (empty($token)) {
            return ['success' => false, 'message' => 'No valid Mailchimp connection found or token expired'];
        }

        $mapped = $this->mapConfig($config, $triggerData);

        $apiBase = $this->getApiBase($token);
        if (!$apiBase) {
            return ['success' => false, 'message' => 'Failed to determine Mailchimp API datacenter'];
        }

        $listId = $mapped['list_id'];

        $fields = $mapped['merge_fields'] ?? '{}';
        if (is_string($fields)) {
            $fields = json_decode($fields, true);
        }
        if (!is_array($fields)) {
            $fields = [];
        }

        $email = $fields['email_address'] ?? '';
        if (empty($email)) {
            return ['success' => false, 'message' => 'Email address is required in the field mapping'];
        }

        $emailHash = md5(strtolower(trim($email)));

        $body = [
            'email_address' => $email,
        ];

        if (!empty($mapped['status'])) {
            $body['status'] = $mapped['status'];
        }

        // Separate merge fields from the email_address entry
        unset($fields['email_address']);
        if (!empty($fields)) {
            $body['merge_fields'] = $fields;
        }

        if (!empty($mapped['language'])) {
            $body['language'] = $mapped['language'];
        }

        if (isset($mapped['vip'])) {
            $body['vip'] = (bool) $mapped['vip'];
        }

        $url = "{$apiBase}/lists/{$listId}/members/{$emailHash}";
        $response = wp_remote_request($url, [
            'method'  => 'PUT',
            'headers' => [
                'Content-Type'  => 'application/json',
                'Authorization' => 'Bearer ' . $token,
            ],
            'body'    => wp_json_encode($body),
            'timeout' => 30,
        ]);

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

        $statusCode   = wp_remote_retrieve_response_code($response);
        $responseBody = json_decode(wp_remote_retrieve_body($response), true);
        $success      = $statusCode >= 200 && $statusCode < 300;

        return [
            'success' => $success,
            'message' => $success
                ? 'Member updated successfully'
                : 'Failed to update member (HTTP ' . $statusCode . '): ' . ($responseBody['detail'] ?? 'Unknown error'),
            'data' => [
                'id'            => $responseBody['id'] ?? '',
                'email_address' => $responseBody['email_address'] ?? '',
                'status'        => $responseBody['status'] ?? '',
            ],
        ];
    }

    private function getApiBase(string $token): ?string
    {
        $response = wp_remote_get('https://login.mailchimp.com/oauth2/metadata', [
            'headers' => ['Authorization' => 'OAuth ' . $token],
            'timeout' => 15,
        ]);

        if (is_wp_error($response)) {
            return null;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);

        if (!empty($body['api_endpoint'])) {
            return rtrim($body['api_endpoint'], '/') . '/3.0';
        }

        return !empty($body['dc'])
            ? 'https://' . $body['dc'] . '.api.mailchimp.com/3.0'
            : null;
    }
}
