<?php
/**
 * Trip Pricings Helper.
 *
 * @package tripzzy
 */

namespace Tripzzy\Core\Helpers;

defined( 'ABSPATH' ) || exit;

/**
 * Price Category class.
 */
class TripPackageCategory {

	/**
	 * Pricing data.
	 *
	 * @var array $data
	 */
	protected $data = array();

	/**
	 * Pricing category/term id.
	 *
	 * @var int ID.
	 */
	protected $id = null;

	/**
	 * Price Per value.
	 *
	 * @var string price per value. ['person' | 'group']
	 */
	public $price_per = 'person';

	/**
	 * Term object instance.
	 *
	 * @var object term object
	 */
	public $term = null;

	/**
	 * Constructor.
	 *
	 * @param array $data Data.
	 * @throws \Exception If error occur or data is empty.
	 */
	public function __construct( $data ) {
		if ( ! isset( $data['id'] ) ) {
			throw new \Exception( esc_html__( 'Arguments array must contains `id`', 'tripzzy' ) );
		}
		$this->id        = $data['id'];
		$this->term      = get_term( $this->id );
		$this->data      = $data;
		$this->price_per = $data['price_per'];
	}

	/**
	 * Gets Pricing ID.
	 *
	 * @return int
	 */
	public function get_id() {
		return $this->id;
	}

	/**
	 * Get Title.
	 *
	 * @return string
	 */
	public function get_title() {
		return $this->term->name ?? '';
	}

	/**
	 * Get Data.
	 *
	 * @since 1.2.1
	 * @return array
	 */
	public function get_data() {
		return $this->data;
	}

	/**
	 * Gets Actual Price.
	 *
	 * @since 1.4.0 Added parameters in has_sale method.
	 * @since 1.3.1 Added quantity parameter to get price based on quantity.
	 * @since 1.0.0
	 *
	 * @param int    $qty Number of people.
	 * @param object $trip Trip object.
	 * @param object $package Package object.
	 * @param object $package_category Package Category object.
	 * @param string $start_date Start date.
	 * @return float
	 */
	public function get_price( $qty = '', $trip = null, $package = null, $package_category = null, $start_date = null ) {
		return $this->has_sale( $qty, $trip, $package, $package_category, $start_date ) ? $this->get_sale_price( $qty, $trip, $package, $package_category, $start_date ) : $this->get_regular_price( $qty, $trip, $package, $package_category, $start_date );
	}

	/**
	 * Gets Price.
	 *
	 * @since 1.3.1 Added quantity, trip, package, package_category, start_date parameters to get sale price based on params.
	 * @since 1.0.0
	 *
	 * @param int    $qty Number of people.
	 * @param object $trip Trip object.
	 * @param object $package Package object.
	 * @param object $package_category Package Category object.
	 * @param string $start_date Start date.
	 * @return int|float
	 */
	public function get_regular_price( $qty = '', $trip = null, $package = null, $package_category = null, $start_date = null ) {
		if ( 'person' === $this->price_per ) {
			$price = isset( $this->data['price'] ) ? (float) $this->data['price'] : 0;
		} else {
			$price = isset( $this->data['group_price'] ) ? (float) $this->data['group_price'] : 0;
		}
		// filter hook with qty and data. @since 1.3.1.
		$price = apply_filters(
			'tripzzy_filter_get_regular_price',
			$price,
			$this->data,
			$qty,
			$trip,
			$package,
			$package_category,
			$start_date
		);
		return $price;
	}

	/**
	 * Returns sale price if category has sale.
	 *
	 * @since 1.3.1 Added quantity, trip, package, package_category, start_date parameters to get sale price based on params.
	 * @since 1.0.0
	 *
	 * @param int    $qty Number of people.
	 * @param object $trip Trip object.
	 * @param object $package Package object.
	 * @param object $package_category Package Category object.
	 * @param string $start_date Start date.
	 * @return int|float
	 */
	public function get_sale_price( $qty = null, $trip = null, $package = null, $package_category = null, $start_date = null ) {

		if ( 'person' === $this->price_per ) {
			$price = isset( $this->data['sale_price'] ) ? (float) $this->data['sale_price'] : 0;
		} else {
			$price = isset( $this->data['group_sale_price'] ) ? (float) $this->data['group_sale_price'] : 0;
		}
		// filter hook with qty and data. @since 1.3.1.
		$price = apply_filters(
			'tripzzy_filter_get_sale_price',
			$price,
			$this->data,
			$qty,
			$trip,
			$package,
			$package_category,
			$start_date
		);
		return $price;
	}

	/**
	 * Return if price catgory has sale.
	 *
	 * @param int    $qty Number of people.
	 * @param object $trip Trip object.
	 * @param object $package Package object.
	 * @param object $package_category Package Category object.
	 * @param string $start_date Start date.
	 *
	 * @since 1.4.0 Added parameters in has_sale method.
	 * @since 1.0.0
	 *
	 * @return boolean
	 */
	public function has_sale( $qty = '', $trip = null, $package = null, $package_category = null, $start_date = null ) {
		return (bool) $this->get_sale_price( $qty, $trip, $package, $package_category, $start_date );
	}

	/**
	 * Return Sale percent if available.
	 *
	 * @since 1.2.7 Added filter to modify sale percent.
	 * @since 1.0.6 Sale percentage issue with -ve value.
	 * @since 1.0.0
	 * @return void
	 */
	public function get_sale_percent() {
		if ( ! $this->has_sale() ) {
			return;
		}
		$percent = ( 100 - ( ( $this->get_price() * 100 ) / $this->get_regular_price() ) );
		$percent = number_format( $percent, 2 );

		$percent = $percent > 0 ? $percent : 0;
		/**
		 * Filter to modify sale percent.
		 *
		 * @since 1.2.7
		 */
		return apply_filters( 'tripzzy_filter_get_sale_percent', $percent, $this );
	}

	/**
	 * Get Group Discount Data For Price Per Person only.
	 *
	 * @internal To Get Group Discount data as per price per group use TripPackage::get_group_discount().
	 *
	 * @param array $args Category Group Discount args.
	 * @since 1.3.1
	 * @return array
	 */
	public function get_group_discount( $args = array() ) {

		return apply_filters(
			'tripzzy_filter_category_get_group_discount',
			array(),
			$this,
			$args['start_date'] ?? null,
			$args['trip'] ?? null,
			$args['package'] ?? null
		);
	}


	/**
	 * Returns if the category is default for the trip.
	 *
	 * @return boolean
	 */
	public function is_default() {
		return ! empty( $this->data['use_as_default'] ) && '1' === $this->data['use_as_default'];
	}
}
