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

declare(strict_types=1);

namespace BookiFlex\Core\Model\DateUnit;

defined( 'ABSPATH' ) || exit;

/**
 *  Check sequence of restrictions for each DateUnit in the period.
 *  And return array of restrictions if they exist.
 */
class RestrictionsChecker
{
    private array $ignoreRestrictions = [];

    /**
     * @param DateUnit[] $dateUnits
     * @param \DateTimeImmutable $dateFrom
     * @param \DateTimeImmutable $dateTo
     *
     * @return array Array of restrictions
     * @throws \Exception
     */
    public function check(
        array $dateUnits,
        \DateTimeImmutable $dateFrom,
        \DateTimeImmutable $dateTo
    ): array {
        $result = [];

        /** DateUnit $unit */
        foreach ($dateUnits as $unit) {
            if ($restrictions = $unit->checkRestrictionsOnPeriod($dateFrom, $dateTo)) {
                $date = $unit->getDate();

                $result[] = [
                    'date'              => $date,
                    'ratePlan'          => $unit->getRatePlanId(),
                    'accommodationType' => $unit->getAccommodationTypeId(),
                    'restrictions'      => $this->filterRestrictions($restrictions),
                ];
            }
        }

        return $result;
    }

    protected function filterRestrictions(array $restrictions): array
    {
        return array_filter($restrictions, function ($item) {
            return !in_array($item, $this->ignoreRestrictions);
        });
    }

    public function configRestrictionRules(RestrictionRulesConfigurator $rules): void
    {
        $this->ignoreRestrictions = [];

        if ($rules->isIgnoreStopSaleRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::STOP_SALE_TYPE;
        }

        if ($rules->isIgnoreMinLosRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MIN_LOS_TYPE;
        }

        if ($rules->isIgnoreMaxLosRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MAX_LOS_TYPE;
        }

        if ($rules->isIgnoreMinLosArrivalRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MIN_LOS_ARRIVAL_TYPE;
        }

        if ($rules->isIgnoreMaxLosArrivalRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MAX_LOS_ARRIVAL_TYPE;
        }

        if ($rules->isIgnoreMinAdvBookingRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MIN_ADV_BOOKING_TYPE;
        }

        if ($rules->isIgnoreMaxAdvBookingRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::MAX_ADV_BOOKING_TYPE;
        }

        if ($rules->isIgnoreCTARestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::CTA_TYPE;
        }

        if ($rules->isIgnoreCTDRestriction()) {
            $this->ignoreRestrictions[] = DateUnitTypeInterface::CTD_TYPE;
        }
    }
}
