<?php

namespace EasyLinkAutomations\Automation;

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

/**
 * Maps placeholders in strings to actual values from trigger data.
 *
 * Supports syntax: {{field_name}}, {{field_name.nested}}, {{field_name|default}}
 */
final class DataMapper
{
    /**
     * Map placeholders in a string to values from data array.
     *
     * @param string $template String with {{placeholder}} syntax
     * @param array  $data     Key-value pairs to substitute
     */
    public static function map(string $template, array $data): string
    {
        return preg_replace_callback(
            '/\{\{([^}]+)\}\}/',
            function ($matches) use ($data) {
                return self::resolveValue($matches[1], $data);
            },
            $template
        );
    }

    /**
     * Resolve a single placeholder to its value.
     *
     * Supports:
     * - Simple: {{field_name}}
     * - Nested: {{object.property.subproperty}}
     * - Default: {{field_name|default_value}}
     */
    private static function resolveValue(string $placeholder, array $data): string
    {
        $placeholder = trim($placeholder);

        // Check for default value
        $default = '';
        if (str_contains($placeholder, '|')) {
            [$placeholder, $default] = explode('|', $placeholder, 2);
            $placeholder = trim($placeholder);
            $default     = trim($default);
        }

        // Handle nested properties (dot notation)
        $parts = explode('.', $placeholder);
        $value = $data;

        foreach ($parts as $part) {
            if (is_array($value) && isset($value[$part])) {
                $value = $value[$part];
            } elseif (is_object($value) && isset($value->$part)) {
                $value = $value->$part;
            } else {
                return $default;
            }
        }

        // Convert arrays/objects to JSON string
        if (is_array($value) || is_object($value)) {
            return wp_json_encode($value);
        }

        return (string) $value;
    }

    /**
     * Extract all placeholders from a template string.
     *
     * @return array<string> List of placeholder names
     */
    public static function extractPlaceholders(string $template): array
    {
        preg_match_all('/\{\{([^}|]+)/', $template, $matches);

        return array_map('trim', $matches[1] ?? []);
    }

    /**
     * Check if a string contains any placeholders.
     */
    public static function hasPlaceholders(string $template): bool
    {
        return str_contains($template, '{{') && str_contains($template, '}}');
    }
}
