<?php

declare(strict_types=1);

namespace BookiFlex\Core\ORM\DataProvider;

use BookiFlex\Core\Admin\CPT\AccommodationType;
use BookiFlex\Core\Admin\CPT\CancellationPolicy;
use BookiFlex\Core\Admin\CPT\RatePlan;

defined( 'ABSPATH' ) || exit;

/**
 * Static normalizers for core CPT meta fields.
 * Each method handles only its own post type's field constants.
 * Registered via CarbonFieldsParser::registerNormalizer() in CoreServiceProvider.
 */
class CoreNormalizers
{
    public static function accommodationType(array $data): array
    {
        $result = [];
        foreach ($data as $key => $value) {
            $result[$key] = match ($key) {
                AccommodationType::FIELD_SHORT_CODE,
                AccommodationType::FIELD_LIVING_SPACE,
                AccommodationType::FIELD_ACCOMMODATION_CATEGORY,
                AccommodationType::FIELD_KEY_AMENITIES,
                AccommodationType::FIELD_ADDRESS,
                AccommodationType::FIELD_PHONE,
                AccommodationType::FIELD_EMAIL,
                AccommodationType::FIELD_LONGITUDE,
                AccommodationType::FIELD_LATITUDE       => isset($value[0]) ? (string) $value[0]['value'] : '',
                AccommodationType::FIELD_MAIN_SLEEPING_ALLOWED_OCCUPANCY,
                AccommodationType::FIELD_ENABLE_EXTRA_OCCUPANCY => array_map(fn($item) => (int) $item['value'], $value),
                AccommodationType::FIELD_CHILD_ALLOWED_ON_MAIN_PLACE,
                AccommodationType::FIELD_CHILD_ALLOWED_ON_EXTRA_PLACE,
                AccommodationType::FIELD_CHILD_ALLOWED_WITHOUT_PLACE => array_map(fn ($item) => (string)$item['value'], $value),
                AccommodationType::FIELD_ACCOMMODATION_GALLERY  => array_map(fn($item) => $item['value'], $value),
                AccommodationType::FIELD_MAIN_SLEEPING_CAPACITY,
                AccommodationType::FIELD_ADDITIONAL_SLEEPING_PLACES,
                AccommodationType::FIELD_ACCOMMODATION_AVAILABLE_UNITS => (int) $value[0]['value'],
                default => count($value) > 1
                    ? array_map(fn($item) => $item['value'], $value)
                    : $value[0]['value'],
            };
        }

        return $result;
    }

    public static function ratePlan(array $data): array
    {
        $result = [];
        foreach ($data as $key => $value) {
            $result[$key] = match ($key) {
                RatePlan::FIELD_SHORT_CODE,
                RatePlan::FIELD_BOARD_TYPE               => isset($value[0]) ? (string) $value[0]['value'] : '',
                RatePlan::FIELD_PAYMENT_TYPES,
                RatePlan::FIELD_ACCOMMODATION_TYPES,
                RatePlan::FIELD_CANCELLATION_POLICY      => array_map(fn($item) => (int) $item['id'], $value),
                RatePlan::FIELD_INHERITANCE_PRICE_RULES  => !empty($value)
                    ? array_map(
                        fn(array $item) => [
                            RatePlan::FIELD_INHERITANCE_PRICE_RULES_PLACEMENTS         => array_map(fn($i) => $i['value'], $item[RatePlan::FIELD_INHERITANCE_PRICE_RULES_PLACEMENTS] ?? []),
                            RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_TYPE      => $item[RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_TYPE][0]['value'] ?? null,
                            RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_ADJUSTMENT => $item[RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_ADJUSTMENT][0]['value'] ?? null,
                            RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_VALUE     => isset($item[RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_VALUE][0]['value'])
                                ? (int) $item[RatePlan::FIELD_INHERITANCE_PRICE_RULES_STRATEGY_VALUE][0]['value']
                                : null,
                        ],
                        $value
                    )
                    : null,
                RatePlan::FIELD_INHERITANCE_RESTRICTIONS => !empty($value)
                    ? array_map(fn($item) => $item['value'], $value)
                    : null,
                default => count($value) > 1
                    ? array_map(fn($item) => $item['value'], $value)
                    : $value[0]['value'],
            };
        }

        return $result;
    }

    public static function cancellationPolicy(array $data): array
    {
        $result = [];
        foreach ($data as $key => $value) {
            $result[$key] = match ($key) {
                CancellationPolicy::FIELD_RULES => !empty($value)
                    ? array_map(
                        fn(array $item) => [
                            CancellationPolicy::FIELD_PENALTY_TYPE                    => $item[CancellationPolicy::FIELD_PENALTY_TYPE][0]['value'] ?? null,
                            CancellationPolicy::FIELD_CANCELLED_WITHIN_HOURS          => isset($item[CancellationPolicy::FIELD_CANCELLED_WITHIN_HOURS][0]['value'])
                                ? (int) $item[CancellationPolicy::FIELD_CANCELLED_WITHIN_HOURS][0]['value']
                                : null,
                            CancellationPolicy::FIELD_CANCELLED_MIN_HOURS_UNTIL_START => isset($item[CancellationPolicy::FIELD_CANCELLED_MIN_HOURS_UNTIL_START][0]['value'])
                                ? (int) $item[CancellationPolicy::FIELD_CANCELLED_MIN_HOURS_UNTIL_START][0]['value']
                                : null,
                            CancellationPolicy::FIELD_CANCELLED_MAX_HOURS_UNTIL_START => isset($item[CancellationPolicy::FIELD_CANCELLED_MAX_HOURS_UNTIL_START][0]['value'])
                                ? (int) $item[CancellationPolicy::FIELD_CANCELLED_MAX_HOURS_UNTIL_START][0]['value']
                                : null,
                            CancellationPolicy::FIELD_FIXED_AMOUNT                    => isset($item[CancellationPolicy::FIELD_FIXED_AMOUNT][0]['value']) && is_numeric($item[CancellationPolicy::FIELD_FIXED_AMOUNT][0]['value'])
                                ? (float) $item[CancellationPolicy::FIELD_FIXED_AMOUNT][0]['value']
                                : null,
                            CancellationPolicy::FIELD_PERCENTAGE_OF_BOOKING_AMOUNT    => isset($item[CancellationPolicy::FIELD_PERCENTAGE_OF_BOOKING_AMOUNT][0]['value']) && is_numeric($item[CancellationPolicy::FIELD_PERCENTAGE_OF_BOOKING_AMOUNT][0]['value'])
                                ? (int) $item[CancellationPolicy::FIELD_PERCENTAGE_OF_BOOKING_AMOUNT][0]['value']
                                : null,
                            CancellationPolicy::FIELD_CHARGE_X_NIGHTS                => isset($item[CancellationPolicy::FIELD_CHARGE_X_NIGHTS][0]['value']) && is_numeric($item[CancellationPolicy::FIELD_CHARGE_X_NIGHTS][0]['value'])
                                ? (int) $item[CancellationPolicy::FIELD_CHARGE_X_NIGHTS][0]['value']
                                : null,
                        ],
                        $value
                    )
                    : null,
                default => count($value) > 1
                    ? array_map(fn($item) => $item['value'], $value)
                    : $value[0]['value'],
            };
        }

        return $result;
    }
}
