<?php
/**
 * API Cache.
 *
 * @package PaczkomatyInpost
 */

/**
 * Can cache ShipX API data.
 */
class WPDesk_Paczkomaty_ShipX_Cache {

	const TRANSIENT_CACHE_TIME = 86400; // 60 * 60 * 24.
	const TRANSIENT_CACHE_PREFIX = 'inpost';

	const PARCEL_LOCKER_ONLY_STRING = 'parcel_locker_only';

	const PARCEL_LOCKER = [ 'parcel_locker' ];
	const PARCEL_LOCKER_ONLY = [ self::PARCEL_LOCKER_ONLY_STRING ];
	const PARCEL_LOCKER_AND_POP = [ 'parcel_locker', 'pop' ];

	/**
	 * Api
	 *
	 * @var WPDesk_Paczkomaty_ShipX
	 */
	private $api;

	/**
	 * Points
	 *
	 * @var WPDesk_Paczkomaty_ShipX_Points
	 */
	private $points;

	/**
	 * Dispatch points
	 *
	 * @var WPDesk_Paczkomaty_ShipX_Dispatch_Points
	 */
	private $dispatch_points;

	/**
	 * Test mode suffix
	 *
	 * @var string
	 */
	private $test_mode_suffix = '';

	/**
	 * Transient names
	 *
	 * @var array
	 */
	private $transient_names = [];

	/**
	 * WPDesk_Paczkomaty_ShipX_Cache constructor.
	 *
	 * @param WPDesk_Paczkomaty_ShipX $api API ShipX.
	 */
	public function __construct( $api ) {
		$this->api = $api;
		if ( $this->api->get_test_mode() ) {
			$this->test_mode_suffix .= '_t';
		}
		$this->prepare_transient_names();
		$this->points          = new WPDesk_Paczkomaty_ShipX_Points( $this->api );
		$this->dispatch_points = new WPDesk_Paczkomaty_ShipX_Dispatch_Points( $this->api );
	}

	/**
	 * Prepare transient names
	 */
	private function prepare_transient_names() {
		$this->transient_names = [
			'organizations'           => $this->prepare_transient_name( 'orgs' ),
			'points'                  => $this->prepare_transient_name( 'points' ),
			'points_options'          => $this->prepare_transient_name( 'points_o' ),
			'dispatch_points'         => $this->prepare_transient_name( 'd_points' ),
			'dispatch_points_options' => $this->prepare_transient_name( 'd_points_o' ),
		];
		foreach ( $this->api->point_types as $key => $value ) {
			$this->transient_names[ 'points' . $key ]                 = $this->prepare_transient_name( 'points' . $value );
			$this->transient_names[ 'points_options' . $key ]         = $this->prepare_transient_name( 'points_o' . $value );
			$this->transient_names[ 'points' . $key . 'cod' ]         = $this->prepare_transient_name( 'points' . $value );
			$this->transient_names[ 'points_options' . $key . 'cod' ] = $this->prepare_transient_name( 'points_o' . $value );
		}
	}

	/**
	 * Prepare single transienent name
	 *
	 * @param string $short_name Short name.
	 *
	 * @return string
	 */
	private function prepare_transient_name( $short_name ) {
		return self::TRANSIENT_CACHE_PREFIX . '_' . $short_name . $this->test_mode_suffix;
	}

	/**
	 * Clear cache
	 */
	public function clear_cache() {
		foreach ( $this->transient_names as $transient_name ) {
			delete_transient( $transient_name );
			delete_option( $transient_name );
			delete_option( $transient_name . '_timeout' );
		}
	}

	/**
	 * Get points.
	 *
	 * @param string $type Type.
	 *
	 * @return array|mixed
	 * @throws WPDesk_Paczkomaty_ShipX_Exception .
	 */
	public function get_points() {
		return $this->points->get_points_from_api( '' );
	}

	/**
	 * Get points options - for selects
	 *
	 * @param array $points_types .
	 *
	 * @return array
	 * @throws Exception|WPDesk_Paczkomaty_ShipX_Exception .
	 */
	public function get_points_options() {
		$points_options = [];
		foreach ( $this->get_points() as $point ) {
			$points_options[ $point->name ] = json_decode( json_encode( $point ), true );
		}

		return $points_options;
	}

	/**
	 * Get dispatch points
	 *
	 * @param bool $force_reload Force reload from API.
	 *
	 * @return array|mixed
	 * @throws WPDesk_Paczkomaty_ShipX_Exception
	 */
	public function get_dispatch_points( $force_reload = false ) {
		$transient_name  = $this->transient_names['dispatch_points'];
		$dispatch_points = get_transient( $transient_name );
		if ( false === $dispatch_points || $force_reload ) {
			$dispatch_points = $this->dispatch_points->get_dispatch_points_from_api();
			set_transient( $transient_name, $dispatch_points, self::TRANSIENT_CACHE_TIME );
		}

		return $dispatch_points;
	}

	/**
	 * Get dispatch points options - for selects
	 *
	 * @return array|bool|mixed
	 * @throws WPDesk_Paczkomaty_ShipX_Exception
	 */
	public function get_dispatch_points_options() {
		$transient_name          = $this->transient_names['dispatch_points_options'];
		$dispatch_points_options = get_transient( $transient_name );
		if ( false === $dispatch_points_options ) {
			$dispatch_points_options = [];
			$dispatch_points         = $this->get_dispatch_points( true );
			foreach ( $dispatch_points as $name => $value ) {
				$dispatch_points_options[ $name ] = $this->dispatch_points->get_dispatch_point_label( $value );
			}
			set_transient( $transient_name, $dispatch_points_options, self::TRANSIENT_CACHE_TIME );
		}

		return $dispatch_points_options;
	}

	/**
	 * @return mixed
	 * @throws Exception .
	 * @throws WPDesk_Paczkomaty_ShipX_Exception .
	 */
	public function get_organizations() {
		$transient_name = $this->transient_names['organizations'];
		$organizations  = get_transient( $transient_name );
		if ( false === $organizations ) {
			$shipx_organizations = $this->api->get_organizations();
			$organizations       = $shipx_organizations->items;
			set_transient( $transient_name, $organizations, self::TRANSIENT_CACHE_TIME );
		}

		return $organizations;
	}
}
