<?php

namespace EasyLinkAutomations\Actions\ActiveCampaign;

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

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

/**
 * Action that creates a new contact in ActiveCampaign.
 *
 * Uses ActiveCampaign API v3.
 * Optionally uses the contact/sync endpoint to update if the email already exists.
 */
final class CreateContactAction extends BaseAction
{
    public static function getSlug(): string
    {
        return 'active_campaign/create_contact';
    }

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

    public static function getDescription(): string
    {
        return __('Create a new contact in ActiveCampaign', 'easylink-automations');
    }

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

    public static function getIcon(): string
    {
        return 'active-campaign';
    }


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

    public static function getConfigFields(): array
    {
        return [
            'update_if_exists' => [
                'label'       => 'Update If Exists',
                'type'        => 'toggle',
                'required'    => false,
                'default'     => false,
                'description' => 'Use contact/sync endpoint to update if email exists',
            ],
            'fields' => [
                'label'            => 'Contact Fields',
                'type'             => 'field_mapping',
                'required'         => true,
                'remote_source'    => 'active-campaign/contact-fields',
                'depends_on'       => ['connection_id'],
                'options_key'      => 'columns',
                'supports_mapping' => true,
            ],
        ];
    }

    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);
        $connection = Connection::find($connectionId);
        if (!$connection) {
            return ['success' => false, 'message' => 'Connection not found'];
        }

        $creds  = Connection::getCredentials($connection);
        $apiUrl = rtrim($creds['api_url'] ?? '', '/');
        $apiKey = $creds['api_key'] ?? '';
        if (empty($apiUrl) || empty($apiKey)) {
            return ['success' => false, 'message' => 'Invalid ActiveCampaign credentials'];
        }

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

        // Decode field mapping data
        $fields = $mapped['fields'] ?? '{}';
        if (is_string($fields)) {
            $fields = json_decode($fields, true);
        }
        if (!is_array($fields)) {
            $fields = [];
        }

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

        $contact = ['email' => $email];

        if (!empty($fields['firstName'])) {
            $contact['firstName'] = $fields['firstName'];
        }

        if (!empty($fields['lastName'])) {
            $contact['lastName'] = $fields['lastName'];
        }

        if (!empty($fields['phone'])) {
            $contact['phone'] = $fields['phone'];
        }

        // Remove standard fields, remaining are custom fields (prefixed with custom_)
        unset($fields['email'], $fields['firstName'], $fields['lastName'], $fields['phone']);

        $fieldValues = [];
        foreach ($fields as $fieldKey => $fieldValue) {
            if ($fieldValue !== '' && $fieldValue !== null && str_starts_with($fieldKey, 'custom_')) {
                $fieldValues[] = [
                    'field' => str_replace('custom_', '', $fieldKey),
                    'value' => (string) $fieldValue,
                ];
            }
        }

        if (!empty($fieldValues)) {
            $contact['fieldValues'] = $fieldValues;
        }

        $updateIfExists = !empty($mapped['update_if_exists']);
        $endpoint = $updateIfExists
            ? "{$apiUrl}/api/3/contact/sync"
            : "{$apiUrl}/api/3/contacts";

        $response = wp_remote_request($endpoint, [
            'method'  => 'POST',
            'headers' => [
                'Content-Type' => 'application/json',
                'Api-Token'    => $apiKey,
            ],
            'body'    => wp_json_encode(['contact' => $contact]),
            '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
                ? 'Contact created successfully'
                : 'Failed to create contact (HTTP ' . $statusCode . '): ' . ($responseBody['message'] ?? 'Unknown error'),
            'data' => $responseBody['contact'] ?? [],
        ];
    }
}
