<?php

namespace Discountify\Core\Frontend;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Discountify\Core\Frontend\Calculator;

use Discountify\Utils\Singleton;

/**
 * Calculator Class
 *
 * @since 1.0.0
 */
class Coupon extends Calculator {
	use Singleton;

	public function not_in_coupon() {
		return array( 'bulk_pricing' );
	}

	public function get_coupon_discount( $product_id, $quantity, $cart_price ) {
		$result_data = array(
			'rules_type'         => '',
			'bogo_discount_type' => '',
			'coupon'             => array(),
		);
		$product     = wc_get_product( $product_id );
		$get_rules   = $this->get_rules_type( $product_id );
		if ( $get_rules['success'] === false ) {
			return $result_data;
		}
		$result = $get_rules['data'];

		if ( 'simple' === $result['rules_type'] ) {

			if ( $result['discount_number'] === '' ) {
				return $result_data;
			}

			// Map discount_type to valid WooCommerce coupon types
			// percent_product is not a valid WooCommerce type, map it to percent
			$wc_discount_type = $result['discount_type'];
			if ( $wc_discount_type === 'percent_product' ) {
				$wc_discount_type = 'percent';
			}

			// When 'all' is selected, pass empty array so the WC coupon applies to every product.
			$coupon_product_ids = array();
			if ( $result['discount_in'] === 'product' && ! in_array( 'all', (array) $result['products'], true ) ) {
				$coupon_product_ids = (array) $result['products'];
			}

			$result_data['coupon'] = \Discountify\Utils\Helper::discount_coupon(
				array(
					'amount'                     => $result['discount_number'],
					'product_ids'                => $coupon_product_ids,
					'product_categories'         => $result['discount_in'] === 'category' ? $result['categories'] : array(),
					'exclude_product_categories' => array(),
					'discount_type'              => $wc_discount_type,
				)
			);

		} elseif ( 'bogo' === $result['rules_type'] ) {
			$bogo_discounts                    = $this->multi_discount_type( $result, $quantity, $product->get_price() );
			$result_data['bogo_discount_type'] = $result['bogo_discount_type'];

			// X_X types: bogo_free, bogo_percent, buy_n_get_one, bogo_fixed_price, buy_x_get_x (legacy)
			$xx_types = array( 'buy_x_get_x', 'bogo_free', 'bogo_percent', 'buy_n_get_one', 'bogo_fixed_price' );
			if ( in_array( $result['bogo_discount_type'], $xx_types, true ) ) {
				if ( ! empty( $bogo_discounts['offer_type'] ) && $bogo_discounts['offer_type'] === 'free' ) {
					return $result_data;
				}

				$bogo_discounts = $this->multi_discount_type( $result, $quantity, $cart_price );

				if ( $bogo_discounts['coupon'] === false || $bogo_discounts['discount_number'] === '' ) {
					return $result_data;
				}

				$coupon = \Discountify\Utils\Helper::discount_coupon(
					array(
						'amount'                     => $bogo_discounts['discount_number'],
						'product_ids'                => array(),
						'product_categories'         => array(),
						'exclude_product_categories' => array(),
						'discount_type'              => $bogo_discounts['apply_offer'],
					)
				);

				$result_data['coupon'] = $coupon;
			}
		} elseif ( 'total_spend' === $result['rules_type'] ) {
			$total_spend = $this->total_spend( $result['multi_discounts'], ( (int) $quantity ) * (float) $product->get_price() );

			if ( empty( $total_spend['discount_number'] ) ) {
				return $result_data;
			}

			$result_data['coupon'] = \Discountify\Utils\Helper::discount_coupon(
				array(
					'amount'                     => $total_spend['discount_number'],
					'product_ids'                => array( $product_id ),
					'product_categories'         => array(),
					'exclude_product_categories' => array(),
					'discount_type'              => $total_spend['discount_type'],
				)
			);
		}

		if ( ! in_array( $result['rules_type'], $this->not_in_coupon() ) ) {
			$result_data['rules_type'] = $result['rules_type'] === 'simple' ? 'discount' : $result['rules_type'];
		}

		return $result_data;
	}

	/**
	 * Get simple discount text
	 *
	 * @param [type] $product_id
	 * @return array
	 */
	public function item_discount_check( $product_id, $quantity, $cart_item = array() ) {
		$result_data = array(
			'type'      => '',
			'msg_label' => esc_html__( 'Discount', 'discountify' ),
			'message'   => '',
			'data'      => array(),
		);

		$result = $this->get_rules_type( $product_id );

		if ( $result['success'] === false ) {
			return $result_data;
		}
		$result_data['rules_type'] = $result['data']['rules_type'];
		if ( 'simple' === $result['data']['rules_type'] ) {

			$result_data['message'] = \Discountify\Utils\Helper::discount_number_with_label( $result['data'] );
		} elseif ( 'bulk_pricing' === $result['data']['rules_type'] ) {
			$product             = wc_get_product( $product_id );
			$price               = $product->get_price();
			$bulk_pricing        = $this->multi_discount_type( $result['data'], $quantity, $price );
			$result_data['data'] = $bulk_pricing;
			if ( $bulk_pricing['discount_number'] !== '' ) {
				$bulk_pricing['discount_type'] = $bulk_pricing['offer_type'];
				$result_data['message']        = $quantity . '*' . $bulk_pricing['apply_discount_number'] . ' (' . \Discountify\Utils\Helper::discount_symbol( $bulk_pricing ) . ')';
			}
		} elseif ( 'bogo' === $result['data']['rules_type'] && in_array( $result['data']['bogo_discount_type'], array( 'buy_x_get_x', 'bogo_free', 'bogo_percent', 'buy_n_get_one', 'bogo_fixed_price' ), true ) ) {
			$product                  = wc_get_product( $product_id );
			$bogo_discounts           = $this->multi_discount_type( $result, $quantity, $product->get_price() );
			$result_data['msg_label'] = esc_html__( 'Bogo', 'discountify' );
			if ( 'free' === $bogo_discounts['offer_type'] ) {
				$result_data['message'] = esc_html__( 'Free', 'discountify' ) . ' ' . $bogo_discounts['free_quantity'] . ' ' . esc_html__( 'Item', 'discountify' );
			} else {
				$result_data['message'] = $this->bogo_discounts_message( $bogo_discounts['offer_type'], $bogo_discounts['discount_number'] );
			}
		}
		if ( 'bogo' === $result['data']['rules_type'] && in_array( $result['data']['bogo_discount_type'], array( 'buy_x_get_y', 'category_bogo' ), true ) ) {

			$result_data = $this->bogo_x_y_offer_check( $cart_item );
			if ( 'category_bogo' === $result['data']['bogo_discount_type'] ) {
				$result_data['msg_label'] = '';
			}

		}

		return $result_data;
	}

	/**
	 * Format BOGO message
	 *
	 * @param [type] $offer_type
	 * @param [type] $number
	 */
	public function bogo_discounts_message( $offer_type, $number ) {
		$message = '';
		if ( 'fixed' === $offer_type ) {
			$message = ' [' . esc_html__( 'SAVE', 'discountify' ) . ' ' . $number . get_woocommerce_currency_symbol() . ']';
		} elseif ( 'percentage' === $offer_type ) {
			$message = ' [' . esc_html__( 'SAVE', 'discountify' ) . ' ' . $number . '%' . ']';
		}

		return $message;
	}
}
