<?php

namespace EasyLinkAutomations\Actions\MailerLite;

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

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

/**
 * Action that creates a new subscriber in MailerLite.
 *
 * Migrated from n8n: MailerLite v2 (resource: subscriber, operation: create)
 * Uses MailerLite API v2: POST https://connect.mailerlite.com/api/subscribers
 */
final class SubscriberCreateAction extends BaseAction
{
    private const API_BASE = 'https://connect.mailerlite.com/api';

    public static function getSlug(): string
    {
        return 'mailerlite/subscriber_create';
    }

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

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

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

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

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

    public static function getConfigFields(): array
    {
        return [
            'fields' => [
                'label'            => 'Subscriber Fields',
                'type'             => 'field_mapping',
                'required'         => true,
                'remote_source'    => 'mailerlite/fields',
                'depends_on'       => ['connection_id'],
                'options_key'      => 'columns',
                'supports_mapping' => true,
            ],
            'status' => [
                'label'       => 'Status',
                'type'        => 'select',
                'required'    => false,
                'placeholder' => 'Select status...',
                'options'     => [
                    ['value' => 'active', 'label' => 'Active'],
                    ['value' => 'unsubscribed', 'label' => 'Unsubscribed'],
                    ['value' => 'unconfirmed', 'label' => 'Unconfirmed'],
                    ['value' => 'bounced', 'label' => 'Bounced'],
                    ['value' => 'junk', 'label' => 'Junk'],
                ],
                'description' => 'Subscriber status (default: unconfirmed for double opt-in accounts)',
            ],
            'ip_address' => [
                'label'            => 'IP Address',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '192.168.1.1',
                'description'      => 'IP address of the subscriber',
            ],
            'subscribed_at' => [
                'label'            => 'Subscribed At',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '2024-01-15 10:00:00',
                'description'      => 'Date and time when the subscriber subscribed (YYYY-MM-DD HH:MM:SS)',
            ],
            'opted_in_at' => [
                'label'            => 'Opted In At',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '2024-01-15 10:00:00',
                'description'      => 'Date and time when the subscriber opted in (YYYY-MM-DD HH:MM:SS)',
            ],
            'optin_ip' => [
                'label'            => 'Opt-In IP',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '192.168.1.1',
                'description'      => 'IP address used when the subscriber opted in',
            ],
            'unsubscribed_at' => [
                'label'            => 'Unsubscribed At',
                'type'             => 'text',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '2024-01-15 10:00:00',
                'description'      => 'Date and time when the subscriber unsubscribed (YYYY-MM-DD HH:MM:SS)',
            ],
            'resubscribe' => [
                'label'       => 'Resubscribe',
                'type'        => 'toggle',
                'required'    => false,
                'description' => 'Resubscribe a previously unsubscribed subscriber when allowed by MailerLite',
            ],
            'groups' => [
                'label'            => 'Group IDs',
                'type'             => 'textarea',
                'required'         => false,
                'supports_mapping' => true,
                'placeholder'      => '4243829086487936, 14133878422767533',
                'description'      => 'Comma-separated MailerLite group IDs to add the subscriber to',
            ],
        ];
    }

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

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

        // Decode field_mapping data (email required + standard + custom fields)
        $fieldMapping = $mapped['fields'] ?? '{}';
        if (is_string($fieldMapping)) {
            $fieldMapping = json_decode($fieldMapping, true);
        }
        if (!is_array($fieldMapping)) {
            $fieldMapping = [];
        }

        // Extract email (required — returned as a required column by the controller)
        $email = trim($fieldMapping['email'] ?? '');
        if (empty($email)) {
            return ['success' => false, 'message' => 'Email is required'];
        }

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

        // Remaining entries (standard + custom subscriber fields) go in the `fields` object
        unset($fieldMapping['email']);
        $subscriberFields = array_filter($fieldMapping, static function ($value) {
            return $value !== '' && $value !== null;
        });
        if (!empty($subscriberFields)) {
            $body['fields'] = $subscriberFields;
        }

        // Optional top-level fields
        if (!empty($mapped['status'])) {
            $body['status'] = $mapped['status'];
        }
        if (!empty($mapped['ip_address'])) {
            $body['ip_address'] = $mapped['ip_address'];
        }
        if (!empty($mapped['subscribed_at'])) {
            $body['subscribed_at'] = $mapped['subscribed_at'];
        }
        if (!empty($mapped['opted_in_at'])) {
            $body['opted_in_at'] = $mapped['opted_in_at'];
        }
        if (!empty($mapped['optin_ip'])) {
            $body['optin_ip'] = $mapped['optin_ip'];
        }
        if (!empty($mapped['unsubscribed_at'])) {
            $body['unsubscribed_at'] = $mapped['unsubscribed_at'];
        }
        if (!empty($mapped['resubscribe'])) {
            $body['resubscribe'] = true;
        }
        $groups = $this->parseCommaSeparated($mapped['groups'] ?? '');
        if (!empty($groups)) {
            $body['groups'] = $groups;
        }

        $url      = self::API_BASE . '/subscribers';
        $response = wp_remote_request($url, [
            'method'  => 'POST',
            'headers' => [
                'Content-Type'  => 'application/json',
                'Accept'        => '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
                ? 'Subscriber created successfully'
                : 'Failed to create subscriber (HTTP ' . $statusCode . '): ' . ($responseBody['message'] ?? 'Unknown error'),
            'data'    => $responseBody ?? [],
        ];
    }

    private function parseCommaSeparated(mixed $value): array
    {
        if (is_array($value)) {
            $items = $value;
        } else {
            $items = explode(',', (string) $value);
        }

        return array_values(array_filter(array_map('trim', $items), static function (string $item): bool {
            return $item !== '';
        }));
    }
}
