<?php

namespace modules\selfserve\traits;

use modules\selfserve\classes\selfserve_lane;
use modules\selfserve\helpers\selfserve_lane_status;

trait selfserve_lane_cache_t
{
    const CACHE_SELFSERVE_PREFIX = 'selfserve_lane_';
    const CACHE_SELFSERVE_LANE_KEY_STATUS = self::CACHE_SELFSERVE_PREFIX . 'status';
    const CACHE_SELFSERVE_LANE_KEY_STATE = self::CACHE_SELFSERVE_PREFIX . 'state';
    const CACHE_SELFSERVE_LANE_KEY_MODE = self::CACHE_SELFSERVE_PREFIX . 'mode';
    const CACHE_SELFSERVE_LANE_KEY_WASH_START_TIME = self::CACHE_SELFSERVE_PREFIX . 'wash_start_time';

    const CACHE_SELFSERVE_LANE_KEY_RESERVATION_START_TIME = self::CACHE_SELFSERVE_PREFIX . 'lane_reservation_start_time';
    const CACHE_SELFSERVE_LANE_KEY_CUSTOMER_NUMBER = self::CACHE_SELFSERVE_PREFIX . 'customer_number';
    const CACHE_SELFSERVE_LANE_KEY_LICENSE_PLATE = self::CACHE_SELFSERVE_PREFIX . 'license_plate';


    /**
     * Get the cache key for the lane
     * @param int $laneId The ID of the lane
     * @param string $property The property to get the cache key for (self::CACHE_SELFSERVE_LANE_KEY_STATUS, self::CACHE_SELFSERVE_LANE_KEY_STATE, self::CACHE_SELFSERVE_LANE_KEY_MODE, ...)
     * @return string The cache key for the lane
     */
    protected function getLaneCacheKey(int $laneId, string $property): string
    {
        return $property . '_' . $laneId;
    }
    /**
     * Set the cache for a lane property
     * @param int $laneId The ID of the lane
     * @param string $property The property to set the cache for (self::CACHE_SELFSERVE_LANE_KEY_STATUS, self::CACHE_SELFSERVE_LANE_KEY_STATE, self::CACHE_SELFSERVE_LANE_KEY_MODE, ...)
     * @param mixed $value The value to set in the cache
     * @return $this;
     */
    public function setLaneCache(int $laneId, string $property, mixed $value): self
    {
        redis->set($this->getLaneCacheKey($laneId, $property), serialize($value));
        return $this;
    }

    /**
     * Get the cache for a lane property
     * @param int $laneId The ID of the lane
     * @param string $property The property to get the cache for (self::CACHE_SELFSERVE_LANE_KEY_STATUS, self::CACHE_SELFSERVE_LANE_KEY_STATE, self::CACHE_SELFSERVE_LANE_KEY_MODE, ...)
     * @param string|null $class The class name of the expected return type
     * @return mixed The value from the cache
     */
    public function getLaneCache(int $laneId, string $property, string $class = null): mixed
    {
        $cachedValue = redis->get($this->getLaneCacheKey($laneId, $property));
        // If the cached value is not found, return null
        if ($cachedValue === null) {
            return null;
        }
        $value = unserialize($cachedValue);
        // If a class is provided, ensure the value is of that class
        if ($class !== null && !($value instanceof $class)) {
            throw new \UnexpectedValueException("Cached value for lane ID {$laneId} and property {$property} is not of type {$class}");
        }
        return $value;
    }
    /**
     * Clear the cache for a lane property
     * @param int $laneId The ID of the lane
     * @param string $property The property to clear the cache for (self::CACHE_SELFSERVE_LANE_KEY_STATUS, self::CACHE_SELFSERVE_LANE_KEY_STATE, self::CACHE_SELFSERVE_LANE_KEY_MODE, ...)
     * @return $this;
     */
    public function clearLaneCache(int $laneId, string $property): self
    {
        redis->delete($this->getLaneCacheKey($laneId, $property));
        return $this;
    }
}