<?php

namespace EasyLinkAutomations\Actions;

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

use EasyLinkAutomations\Actions\Contracts\ActionInterface;
use EasyLinkAutomations\Automation\DataMapper;

/**
 * Abstract base class for actions.
 *
 * Provides common functionality for all action implementations.
 */
abstract class BaseAction implements ActionInterface
{
    /**
     * Whether this action requires the pro add-on.
     * Override in pro action classes to return true.
     */
    public static function isPro(): bool
    {
        return false;
    }

    /**
     * By default, actions don't require a connection.
     * Override this method in subclasses that need a connection.
     */
    public static function getRequiresConnection(): ?string
    {
        return null;
    }

    /**
     * Map a value using trigger data placeholders.
     *
     * Replaces {{field_name}} with actual values from trigger data.
     * Handles strings directly and recursively processes arrays.
     */
    protected function mapValue(mixed $value, array $triggerData): mixed
    {
        if (is_string($value)) {
            return DataMapper::map($value, $triggerData);
        }

        if (is_array($value)) {
            $mapped = [];
            foreach ($value as $k => $v) {
                $mapped[$k] = $this->mapValue($v, $triggerData);
            }
            return $mapped;
        }

        return $value;
    }

    /**
     * Map all config values that support mapping.
     */
    protected function mapConfig(array $config, array $triggerData): array
    {
        $fields = static::getConfigFields();
        $mapped = [];

        foreach ($config as $key => $value) {
            $supportsMapping = $fields[$key]['supports_mapping'] ?? false;
            $mapped[$key]    = $supportsMapping ? $this->mapValue($value, $triggerData) : $value;
        }

        return $mapped;
    }

    /**
     * Convert action metadata to array for API response.
     */
    public static function toArray(): array
    {
        return [
            'slug'               => static::getSlug(),
            'name'               => static::getName(),
            'description'        => static::getDescription(),
            'category'           => static::getCategory(),
            'icon'               => static::getIcon(),
            'is_pro'             => static::isPro(),
            'requiresConnection' => static::getRequiresConnection(),
            'configFields'       => static::getConfigFields(),
        ];
    }

    /**
     * Validate required fields are present.
     *
     * @return array<string> List of missing required fields
     */
    protected function validateRequired(array $config): array
    {
        $fields  = static::getConfigFields();
        $missing = [];

        foreach ($fields as $key => $field) {
            if (($field['required'] ?? false) && empty($config[$key])) {
                $missing[] = $field['label'] ?? $key;
            }
        }

        return $missing;
    }
}
