<?php

namespace EasyLinkAutomations\Triggers;

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

use EasyLinkAutomations\Triggers\Contracts\TriggerInterface;

/**
 * Abstract base class for triggers.
 *
 * Provides common functionality for all trigger implementations.
 */
abstract class BaseTrigger implements TriggerInterface
{
    /**
     * Callback to execute when trigger fires.
     *
     * @var callable|null
     */
    protected $callback = null;

    /**
     * Call the registered callback with trigger data.
     */
    protected function fire(array $triggerData): void
    {
        if ($this->callback !== null) {
            call_user_func($this->callback, $triggerData);
        }
    }

    /**
     * Recursively flatten a nested array into dot-notation key → scalar pairs.
     *
     * Associative sub-arrays are recursed (e.g. {"user":{"name":"John"}}
     * becomes "user.name" => "John"), matching the dot-notation that
     * DataMapper uses to resolve {{user.name}} placeholders.
     *
     * Sequential (numeric) arrays are JSON-encoded as a single string value.
     *
     * @param array<string|int, mixed> $data
     * @param string                   $prefix Current dot-notation prefix
     *
     * @return array<string, scalar|null>
     */
    public static function flattenFields(array $data, string $prefix = ''): array
    {
        $result = [];

        foreach ($data as $key => $value) {
            $fullKey = $prefix !== '' ? $prefix . '.' . $key : (string) $key;

            if (is_array($value) && !empty($value) && array_keys($value) !== range(0, count($value) - 1)) {
                // Associative (nested object) — recurse with dot-notation prefix
                $result = array_merge($result, static::flattenFields($value, $fullKey));
            } else {
                // Scalar, null, empty array, or sequential list — store as-is or encode
                $result[$fullKey] = is_array($value) ? wp_json_encode($value) : $value;
            }
        }

        return $result;
    }

    /**
     * Convert trigger 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(),
            'available'    => static::isAvailable(),
            'outputFields' => static::getOutputFields(),
            'configFields' => static::getConfigFields(),
        ];
    }

    /**
     * Whether this trigger requires the pro add-on.
     * Override in pro trigger classes to return true.
     */
    public static function isPro(): bool
    {
        return false;
    }

    /**
     * Check if the required plugin/dependency is active.
     * WordPress core triggers are always available — override in plugin-specific triggers.
     */
    public static function isAvailable(): bool
    {
        return true;
    }

    /**
     * Check if automation should run based on config conditions.
     */
    protected function shouldRun(array $config, array $data): bool
    {
        // Override in child classes for custom filtering
        return true;
    }
}
