<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Runtime;

defined('ABSPATH') || exit;

class RuntimeColorMapper
{
    public function buildRuntimeConfig(array $colors, mixed $rawConfig = []) : array
    {
        $config = is_array($rawConfig) ? $rawConfig : [];
        $scope = sanitize_key((string) ($config['scope'] ?? 'object'));
        if (! in_array($scope, ['object', 'canvas', 'document'], true)) {
            $scope = 'object';
        }

        return [
            'scope' => $scope,
            'items' => $this->normalizeItems($colors),
        ];
    }

    public function normalizeItems(array $colors) : array
    {
        $items = [];
        foreach ($colors as $color) {
            if (! is_array($color) || (isset($color['enabled']) && ! $color['enabled'])) {
                continue;
            }
            $normalized = $this->normalizeItem($color, count($items));
            if ($normalized !== null) {
                $items[] = $normalized;
            }
        }

        return $items;
    }

    public function normalizeItem(array $color, int $index = 0) : ?array
    {
        $id = sanitize_key((string) ($color['id'] ?? ''));
        $label = sanitize_text_field((string) ($color['label'] ?? ''));
        $value = trim((string) ($color['value'] ?? ''));
        if ($id === '' || $label === '' || $value === '') {
            return null;
        }

        $type = sanitize_key((string) ($color['type'] ?? 'solid')) ?: 'solid';
        if (! in_array($type, ['solid', 'gradient', 'pattern', 'image'], true)) {
            $type = 'solid';
        }
        $printingMethodMode = sanitize_key((string) ($color['printingMethodMode'] ?? ''));
        $printingMethodIds = is_array($color['printingMethodIds'] ?? null)
            ? array_values(array_unique(array_filter(array_map('sanitize_key', (array) $color['printingMethodIds']))))
            : [];
        if (! in_array($printingMethodMode, ['all', 'restricted', 'none'], true)) {
            $printingMethodMode = $printingMethodIds !== [] ? 'restricted' : 'all';
        }

        return array_replace($color, [
            'id' => $id,
            'label' => $label,
            'value' => $value,
            'type' => $type,
            'price' => $this->toFloat($color['price'] ?? 0),
            'printingMethodMode' => $printingMethodMode,
            'printingMethodIds' => $printingMethodIds,
            'isDefault' => ! empty($color['isDefault']),
            'enabled' => ! isset($color['enabled']) || ! empty($color['enabled']),
        ]);
    }

    public function mapByIdOrValue(array $colors) : array
    {
        $map = [];
        foreach ($this->normalizeItems($colors) as $color) {
            $id = sanitize_key((string) ($color['id'] ?? ''));
            $value = trim((string) ($color['value'] ?? ''));
            if ($id !== '') {
                $map[$id] = $color;
            }
            if ($value !== '') {
                $map[$value] = $color;
            }
        }

        return $map;
    }

    private function toFloat(mixed $value, float $fallback = 0.0) : float
    {
        if (is_numeric($value)) {
            return (float) $value;
        }
        $value = str_replace(',', '.', trim((string) $value));
        return is_numeric($value) ? (float) $value : $fallback;
    }
}
