<?php

namespace App\Services\Courier;

class CourierCostResolver
{
    public function extract(array $payload): array
    {
        return [
            'actual_delivery_cost' => $this->findAmount($payload, [
                'actual_delivery_cost',
                'actual_delivery_charge',
                'delivery_cost',
                'delivery_charge',
                'delivery_fee',
                'delivery_amount',
            ]),
            'actual_return_cost' => $this->findAmount($payload, [
                'actual_return_cost',
                'actual_return_charge',
                'return_cost',
                'return_charge',
                'return_delivery_cost',
                'return_delivery_charge',
                'return_fee',
            ]),
            'actual_cod_charge' => $this->findAmount($payload, [
                'actual_cod_charge',
                'cod_charge',
                'cod_fee',
            ]),
        ];
    }

    private function findAmount(array $payload, array $candidateKeys): ?float
    {
        $normalizedKeys = array_map(fn ($key) => $this->normalizeKey($key), $candidateKeys);

        $iterator = function ($data) use (&$iterator, $normalizedKeys) {
            if (! is_array($data)) {
                return null;
            }

            foreach ($data as $key => $value) {
                if (in_array($this->normalizeKey((string) $key), $normalizedKeys, true)) {
                    $parsed = $this->normalizeAmount($value);
                    if ($parsed !== null) {
                        return $parsed;
                    }
                }

                if (is_array($value)) {
                    $nested = $iterator($value);
                    if ($nested !== null) {
                        return $nested;
                    }
                }
            }

            return null;
        };

        return $iterator($payload);
    }

    private function normalizeKey(string $key): string
    {
        return strtolower(str_replace(['-', ' '], '_', $key));
    }

    private function normalizeAmount($value): ?float
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (is_numeric($value)) {
            return (float) $value;
        }

        if (is_string($value)) {
            $normalized = preg_replace('/[^0-9.\-]/', '', $value);
            if ($normalized !== '' && is_numeric($normalized)) {
                return (float) $normalized;
            }
        }

        return null;
    }
}
