<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Ajax\Handler;

use Configuration;
use Simplyin;
use SimplyIn\Ajax\AjaxActionInterface;
use SimplyIn\Ajax\AjaxRequest;
use SimplyIn\Ajax\Service\CheckoutSessionService;
use SimplyIn\Api\SimplyInApiClient;

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

final class GetClosestParcelLockersHandler implements AjaxActionInterface
{
    public function __construct(
        private readonly SimplyInApiClient $api,
        private readonly Simplyin $module,
        private readonly CheckoutSessionService $checkoutSession,
    ) {
    }

    public function name(): string
    {
        return 'getClosestParcelLockers';
    }

    public function execute(AjaxRequest $request): array
    {
        $availableCarriers = $this->module->getAvailableCarriers();
        if (empty($availableCarriers)) {
            return [];
        }

        $coordinates = $request->getArray('coordinates');
        $authToken = $this->checkoutSession->getAuthToken();
        /** @var array<string, mixed> $params */
        $params = [
            'numberOfItemsToFind',
            'searchRadiusInMeters',
            'coordinates' => [
                'lng' => (float) ($coordinates['lng'] ?? 0),
                'lat' => (float) ($coordinates['lat'] ?? 0),
            ],
            'acceptedParcelLockerProviders' => $availableCarriers,
        ];

        $result = $this->api->apiCall($params, 'POST', 'parcelLockers/getClosest', $authToken ?: null);
        $result = is_array($result) ? $result : ['data' => []];

        $sortBy = json_decode((string) Configuration::get('SIMPLYIN_LOGISTICSPARTNERSORDER'), true);
        if (is_array($sortBy) && $sortBy !== []) {
            $sortBy = array_map('strtolower', array_map('strval', $sortBy));
            $lockers = $result['data'] ?? [];
            if (is_array($lockers)) {
                usort($lockers, function ($a, $b) use ($sortBy) {
                    $aName = strtolower((string) ($a['info']['provider']['name'] ?? ''));
                    $bName = strtolower((string) ($b['info']['provider']['name'] ?? ''));
                    $aIdx = array_search($aName, $sortBy, true);
                    $bIdx = array_search($bName, $sortBy, true);
                    $aIdx = $aIdx === false ? PHP_INT_MAX : $aIdx;
                    $bIdx = $bIdx === false ? PHP_INT_MAX : $bIdx;

                    return $aIdx === $bIdx ? strcasecmp($aName, $bName) : $aIdx <=> $bIdx;
                });
                $result['data'] = $lockers;
            }
        }

        return ['success' => true, 'data' => $result];
    }
}
