<?php
/**
 * Smart Coupons category fields in coupons
 *
 * @author      StoreApps
 * @since       4.8.0
 * @version     1.6.1
 *
 * @package     woocommerce-smart-coupons/includes/
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'WC_SC_Coupon_Categories' ) ) {

	/**
	 * Class for handling Smart Coupons' field in coupons
	 */
	class WC_SC_Coupon_Categories {

		/**
		 * Variable to hold instance of WC_SC_Coupon_Categories
		 *
		 * @var $instance
		 */
		private static $instance = null;

		/**
		 * Get single instance of WC_SC_Coupon_Categories
		 *
		 * @return WC_SC_Coupon_Categories Singleton object of WC_SC_Coupon_Categories
		 */
		public static function get_instance() {
			// Check if instance is already exists.
			if ( is_null( self::$instance ) ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 */
		private function __construct() {
			add_action( 'init', array( $this, 'wc_sc_coupons_add_category' ) );
			add_filter( 'parent_file', array( $this, 'wc_sc_make_menu_active' ) );
			add_action( 'admin_footer', array( $this, 'add_footer_script' ) );
			add_filter( 'manage_edit-sc_coupon_category_columns', array( $this, 'wc_sc_coupon_category_id_column' ) );
			add_filter( 'manage_sc_coupon_category_custom_column', array( $this, 'wc_sc_coupon_category_id_column_content' ), 10, 3 );
			add_filter( 'manage_edit-sc_coupon_category_sortable_columns', array( $this, 'wc_sc_define_sortable_id_columns' ) );
			add_filter( 'manage_shop_coupon_posts_columns', array( $this, 'define_columns' ), 11 );
			add_action( 'manage_shop_coupon_posts_custom_column', array( $this, 'render_columns' ), 10, 2 );
			add_filter( 'is_sc_valid_apply_credit', array( $this, 'validate_applicable_store_credit_against_line_item' ), 11, 4 );
			add_action( 'template_redirect', array( $this, 'wc_sc_redirect_coupon_category_to_shop' ) );
		}

		/**
		 * Handle call to functions which is not available in this class
		 *
		 * @param string $function_name The function name.
		 * @param array  $arguments Array of arguments passed while calling $function_name.
		 * @return result of function call
		 */
		public function __call( $function_name, $arguments = array() ) {

			global $woocommerce_smart_coupon;

			if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
				return;
			}

			if ( ! empty( $arguments ) ) {
				return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
			} else {
				return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
			}
		}

		/**
		 * Register custom taxonomy called sc_coupon_category.
		 */
		public function wc_sc_coupons_add_category() {

			$labels = array(
				'name'              => __( 'Coupon categories', 'woocommerce-smart-coupons' ),
				'singular_name'     => __( 'Category', 'woocommerce-smart-coupons' ),
				'menu_name'         => _x( 'Categories', 'Admin menu name', 'woocommerce-smart-coupons' ),
				'search_items'      => __( 'Search coupon categories', 'woocommerce-smart-coupons' ),
				'all_items'         => __( 'All coupon categories', 'woocommerce-smart-coupons' ),
				'parent_item'       => __( 'Parent coupon category', 'woocommerce-smart-coupons' ),
				'parent_item_colon' => __( 'Parent coupon category:', 'woocommerce-smart-coupons' ),
				'edit_item'         => __( 'Edit coupon category', 'woocommerce-smart-coupons' ),
				'update_item'       => __( 'Update coupon category', 'woocommerce-smart-coupons' ),
				'add_new_item'      => __( 'Add new coupon category', 'woocommerce-smart-coupons' ),
				'new_item_name'     => __( 'New coupon category name', 'woocommerce-smart-coupons' ),
				'not_found'         => __( 'No coupon categories found', 'woocommerce-smart-coupons' ),
			);
			register_taxonomy(
				'sc_coupon_category',       // Taxonomy name.
				array( 'shop_coupon' ),       // object for which the taxonomy is created.
				array(
					'labels'            => $labels,
					'description'       => __( 'Manage coupon categories', 'woocommerce-smart-coupons' ),
					'public'            => true,
					'hierarchical'      => true,
					'show_ui'           => true,
					'show_in_menu'      => false,
					'show_in_rest'      => true,
					'show_admin_column' => true,
					'rewrite'           => array( 'slug' => 'sc_coupon_category' ),
					'query_var'         => true,
				)
			);
			register_taxonomy_for_object_type( 'sc_coupon_category', 'shop_coupon' );
		}

		/**
		 * Function to render coupon category column on coupons dashboard.
		 *
		 * @param int       $post_id The coupon ID.
		 * @param WC_Coupon $coupon The coupon object.
		 */
		public function render_coupon_category_column( $post_id = 0, $coupon = null ) {
			$terms = get_the_terms( $post_id, 'sc_coupon_category' );
			if ( ! empty( $terms ) ) {
				foreach ( $terms as $term ) {
					$content[] = '<a href="' . esc_url( admin_url( 'edit.php?sc_coupon_category=' . $term->slug . '&post_type=shop_coupon' ) ) . '">' . esc_html( $term->name ) . '</a>';
				}
				echo join( ', ', $content ); // phpcs:ignore
			} else {
				echo '<span class="na">&ndash;</span>';
			}
		}

		/**
		 * Function to set woocommerce menu active
		 *
		 * @param string $parent_file file reference for menu.
		 */
		public function wc_sc_make_menu_active( $parent_file ) {
			global $current_screen;

			$taxonomy = $current_screen->taxonomy;
			if ( 'sc_coupon_category' === $taxonomy ) {
				if ( $this->is_wc_gte_44() ) {
					$parent_file = 'woocommerce-marketing';
				} else {
					$parent_file = 'woocommerce';
				}
			}

			return $parent_file;
		}

		/**
		 * Function to add custom script in admin footer.
		 */
		public function add_footer_script() {
			global $pagenow, $post;
			$get_post_type = ( ! empty( $post->ID ) ) ? $this->get_post_type( $post->ID ) : ( ( ! empty( $_GET['post_type'] ) ) ? wc_clean( wp_unslash( $_GET['post_type'] ) ) : '' ); // phpcs:ignore
			if ( 'shop_coupon' === $get_post_type ) {
				if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
					$manage_category_string = __( 'Manage coupon categories', 'woocommerce-smart-coupons' );
					?>
					<script type="text/javascript">
						jQuery(function() {
							jQuery('#sc_coupon_category-tabs').before('<div class="sc-manage-category"><a target="_blank" href="<?php echo esc_url( admin_url( 'edit-tags.php?taxonomy=sc_coupon_category&post_type=shop_coupon' ) ); ?> "><?php echo esc_html( $manage_category_string ); ?></a></div>');
						});
					</script>
					<?php
				}
			}
		}

		/**
		 * Function for add id column in coupon category taxonomy page.
		 *
		 * @param array $columns - Existing headers.
		 * @return array
		 */
		public function wc_sc_coupon_category_id_column( $columns = array() ) {
			if ( ! empty( $columns ) ) {
				return array_slice( $columns, 0, 1, true ) + array( 'id' => 'ID' ) + array_slice( $columns, 1, count( $columns ) - 1, true );
			}

			return $columns;
		}

		/**
		 * Function for add content to ID column of coupon category taxonomy page.
		 *
		 * @param string $content - column content.
		 * @param string $column_name - column_name.
		 * @param string $term_id - id.
		 * @return string
		 */
		public function wc_sc_coupon_category_id_column_content( $content = '', $column_name = '', $term_id = 0 ) {
			return $term_id;
		}

		/**
		 * Function for change ID column to sortable.
		 *
		 * @param array $columns - Existing columns.
		 * @return array
		 */
		public function wc_sc_define_sortable_id_columns( $columns = array() ) {
			$columns['id'] = 'id';
			return $columns;
		}

		/**
		 * Define which columns to show on this screen.
		 *
		 * @param array $columns Existing columns.
		 * @return array
		 */
		public function define_columns( $columns = array() ) {

			if ( ! is_array( $columns ) || empty( $columns ) ) {
				$columns = array();
			}

			$columns['wc_sc_coupon_category'] = __( 'Categories', 'woocommerce-smart-coupons' );

			return $columns;
		}

		/**
		 * Render individual columns.
		 *
		 * @param string $column Column ID to render.
		 * @param int    $post_id Post ID being shown.
		 */
		public function render_columns( $column = '', $post_id = 0 ) {
			try {
				if ( empty( $post_id ) || empty( $column ) || 'wc_sc_coupon_category' !== $column ) {
					return;
				}

				$coupon = new WC_Coupon( $post_id );

				$this->render_coupon_category_column( $post_id, $coupon );
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Function to validate applicable StoreCredit against on line item.
		 *
		 * @param bool            $valid Coupon validity.
		 * @param WC_Product|null $product Product object.
		 * @param WC_Coupon|null  $coupon Coupon object.
		 * @param array|null      $cart_item Cart Item.
		 * @return bool           $valid
		 */
		public function validate_applicable_store_credit_against_line_item( $valid = false, $product = null, $coupon = null, $cart_item = null ) {
			try {
				if ( ! $coupon instanceof WC_Coupon || empty( $cart_item['product_id'] ) ) {
					return $valid;
				}
				$coupon_product_ids   = ! empty( $coupon->get_product_ids() ) ? $coupon->get_product_ids() : array();
				$coupon_category_ids  = ! empty( $coupon->get_product_categories() ) ? $coupon->get_product_categories() : array();
				$product_category_ids = wc_get_product_cat_ids( $cart_item['product_id'] );
				if ( in_array( $cart_item['product_id'], $coupon_product_ids, true ) || in_array( $cart_item['variation_id'], $coupon_product_ids, true ) || count( array_intersect( $product_category_ids, $coupon_category_ids ) ) > 0 ) {
					$valid = true;
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}

			return $valid;
		}

		/**
		 * Redirect sc_coupon_category taxonomy pages to WooCommerce shop page.
		 * Admin users (with 'manage_options' capability) are exempt from this redirect by default.
		 *
		 * @return void
		 *
		 * @filter sc_coupon_category_should_redirect bool  Allows customizing the redirect condition.
		 * @filter sc_coupon_category_redirect_url    string Allows customizing the redirect URL.
		 */
		public function wc_sc_redirect_coupon_category_to_shop() {
			// Default condition: redirect on sc_coupon_category taxonomy pages for non-admins.
			$should_redirect = is_tax( 'sc_coupon_category' ) && ! current_user_can( 'manage_options' );

			/**
			 * Filter the condition to redirect sc_coupon_category taxonomy pages.
			 * Allows developers to customize the redirect behavior.
			 *
			 * @param bool $should_redirect Default condition (true/false).
			 */
			$should_redirect = apply_filters( 'sc_coupon_category_should_redirect', $should_redirect );

			if ( $should_redirect ) {
				// Get WooCommerce shop page URL.
				$shop_page_url = get_permalink( wc_get_page_id( 'shop' ) );

				/**
				 * Filter the redirect URL for sc_coupon_category taxonomy pages.
				 * Allows developers to customize the redirect target URL.
				 *
				 * @param string $shop_page_url Current shop page URL.
				 */
				$shop_page_url = apply_filters( 'sc_coupon_category_redirect_url', $shop_page_url );

				wp_safe_redirect( $shop_page_url );
				exit;
			}
		}
	}

}

WC_SC_Coupon_Categories::get_instance();
