<?php
/**
 * BookiFlex Onboarding Extension
 *
 * @package    BookiFlex
 * @subpackage Onboarding
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Extensions\Onboarding\Api\Transformer;

use BookiFlex\Extensions\Onboarding\ValueObject\Currency;
use BookiFlex\Core\Model\CancellationPolicy\CancellationPolicy;
use BookiFlex\Core\Model\PaymentType\PaymentType;

defined( 'ABSPATH' ) || exit;

/**
 * Init Response Transformer
 *
 * Transforms initialization data (domain objects) to API response format.
 * Returns currencies, cancellation policies, and payment types.
 *
 * @package BookiFlex\Extensions\Onboarding\Api\Transformer
 * @since   1.0.0
 */
class InitResponseTransformer
{
    /**
     * Transform init data to API response format
     *
     * @param  Currency[]           $currencies           Available currencies
     * @param  CancellationPolicy[] $cancellationPolicies Domain objects
     * @param  PaymentType[]        $paymentTypes         Domain objects
     * @param  array                $bookingPresets       Booking presets with resolved IDs
     * @param  array<int, array{value: string, label: string}> $accommodationTypes Accommodation type options
     * @return array{currencies: array, cancellationPolicies: array, paymentTypes: array, bookingPresets: array, accommodationTypes: array} Response array
     */
    public function transform(
        array $currencies,
        array $cancellationPolicies,
        array $paymentTypes,
        array $bookingPresets,
        array $accommodationTypes
    ): array {
        return [
            'currencies' => $this->transformCurrencies($currencies),
            'cancellationPolicies' => $this->transformCancellationPolicies($cancellationPolicies),
            'paymentTypes' => $this->transformPaymentTypes($paymentTypes),
            'bookingPresets' => $bookingPresets,
            'accommodationTypes' => $accommodationTypes,
        ];
    }

    /**
     * Transform Currency value objects to array format
     *
     * @param  Currency[] $currencies Currency objects
     * @return array<int, array{value: string, label: string, symbol: string}> Currency arrays
     */
    private function transformCurrencies(array $currencies): array
    {
        return array_map(
            fn(Currency $currency) => [
                'value' => $currency->value,
                'label' => $currency->label,
                'symbol' => $currency->symbol,
            ],
            $currencies
        );
    }

    /**
     * Transform CancellationPolicy domain objects to API format
     *
     * NOTE: Second item (index 1) is marked as recommended
     *
     * @param  CancellationPolicy[] $policies Domain objects
     * @return array<int, array{id: int, label: string,description: string, recommended: bool}> API format
     */
    private function transformCancellationPolicies(array $policies): array
    {
        $result = [];
        $index = 0;

        foreach ($policies as $policy) {
            $result[] = [
                'id' => $policy->getId(),
                'label' => $policy->getName(),
                'description' => $policy->getDescription(),
                'recommended' => $index === 1, // Second item is recommended
            ];
            $index++;
        }

        return $result;
    }

    /**
     * Transform PaymentType domain objects to API format
     *
     * NOTE: Second item (index 1) is marked as recommended
     *
     * @param  PaymentType[] $paymentTypes Domain objects
     * @return array<int, array{id: int, label: string, description: string, recommended: bool}> API format
     */
    private function transformPaymentTypes(array $paymentTypes): array
    {
        $result = [];
        $index = 0;

        foreach ($paymentTypes as $type) {
            $result[] = [
                'id' => $type->getId(),
                'label' => $type->getName(),
                'description' => $type->getDescription(),
                'recommended' => $index === 1, // Second item is recommended
            ];
            $index++;
        }

        return $result;
    }
}
