<?php
namespace TotalThemeCore\Shortcodes;

defined( 'ABSPATH' ) || exit;

final class Shortcode_Header_Cart_Icon {
	private static $display;
	private static $action;

	/**
	 * Register the shortcode and add filters.
	 */
	public function __construct() {
		add_shortcode( 'header_cart_icon', __CLASS__ . '::output' );

		if ( self::maybe_add_cart_fragments() ) {
			add_filter( 'woocommerce_add_to_cart_fragments', __CLASS__ . '::cart_fragments' );
		}
	}

	/**
	 * Shortcode output.
	 */
	public static function output( $atts = array() ) {
		$display = self::display();
		if ( ! $display || 'disabled' === $display ) {
			return;
		}
		$atts = shortcode_atts( array(
			'class'        => '',
			'visibility'   => '',
			'label'        => '',
			'label_margin' => '',
		), $atts, 'header_cart_icon' );

		$class = '';

		if ( ! empty( $atts['class'] ) ) {
			$class .= ' ' . str_replace( '.', '', trim( $atts['class'] ) );
		}

		if ( ! empty( $atts['visibility'] ) ) {
			$visibility = $atts['visibility'];
			if ( function_exists( 'wpex_visibility_class' ) ) {
				$visibility = wpex_visibility_class( $visibility );
			}
			$class .= ' ' . sanitize_html_class( $visibility );
		}

		$icon = '';

		$html = '<span class="wpex-header-cart-icon wpex-inline-block wpex-relative' . esc_attr( $class ) . '">';
			$action = self::action();
			if ( 'drop_down' === $action || 'overlay' === $action ) {
				$html .= self::get_button( $atts );
			} else {
				$html .= self::get_link( $atts );
			}
		$html .= '</span>';

		return $html;
	}

	/**
	 * Get button.
	 */
	private static function get_button( $atts = array() ) {
		$button = '';

		$aria_controls = 'current-shop-items-dropdown';

		$button .= '<button class="wpex-header-cart-icon__button wpex-unstyled-button wpex-hover-link-color wpex-flex wpex-items-center" aria-expanded="false" aria-controls="' . esc_attr( $aria_controls ) . '">';
			$button .= self::get_label( $atts );
			$button .= self::get_icon();
			$button .= self::get_extras();
		$button .= '</button>';

		return $button;
	}

	/**
	 * Get link.
	 */
	private static function get_link( $atts = array() ) {
		$link = '';
		$url = '#';

		if ( 'custom-link' === self::action() ) {
			$custom_link = get_theme_mod( 'woo_menu_icon_custom_link' );
			if ( $custom_link ) {
				$url = esc_url( $custom_link );
			}
		} elseif ( function_exists( 'wpex_parse_obj_id' ) && function_exists( 'wc_get_page_id' ) ) {
			$cart_id = wpex_parse_obj_id( wc_get_page_id( 'cart' ), 'page' );
			if ( $cart_id ) {
				$url = get_permalink( $cart_id );
			}
		}

		$link .= '<a href="' . esc_url( $url ) . '" class="wpex-header-cart-icon__link wpex-inherit-color wpex-no-underline wpex-hover-link-color wpex-flex wpex-items-center">';
			$link .= self::get_label( $atts );
			$link .= self::get_icon();
			$link .= self::get_extras();
		$link .= '</a>';

		return $link;
	}

	/**
	 * Get label.
	 */
	private static function get_label( $atts ) {
		if ( empty( $atts['label'] ) ) {
			return;
		}
		$style = '';
		if ( ! empty( $atts['label_margin'] ) ) {
			$margin_side = is_rtl() ? 'left' : 'right';
			$style = ' style="margin-' . $margin_side .':' . esc_attr( $atts['label_margin'] ) . ';"';
		}
		return '<span class="wpex-header-cart-icon__label wpex-mr-5"' . $style . '>' . esc_html( $atts['label'] ) . '</span>';
	}

	/**
	 * Get icon.
	 */
	private static function get_icon() {
		$icon = '';

		if ( function_exists( 'wpex_theme_icon_html' ) ) {
			$cart_icon = get_theme_mod( 'woo_menu_icon_class' );
			$cart_icon = $cart_icon ?: 'shopping-cart';
			$icon .= wpex_get_theme_icon_html( $cart_icon );
		}

		/**
		 * Filters the icon html.
		 *
		 * @param string $html
		 */
		$icon = apply_filters( 'wpex_header_search_icon_shortcode_icon_html', $icon );

		return '<span class="wpex-header-cart-icon__icon">' . $icon . '</span>';
	}

	/**
	 * Get extras.
	 */
	private static function get_extras() {
		$display = self::display();
		if ( 'icon_total' !== $display && 'icon_count' !== $display ) {
			return;
		}
		$html = '<span class="wpex-header-cart-icon__fragments wpex-ml-5 wpex-inline-flex">';
			switch ( $display ) {
				case 'icon_total':
					$html .= self::get_cart_price();
					break;
				case 'icon_count':
					$html .= self::get_cart_count();
					break;
			}
		$html .= '</span>';
		return $html;
	}

	/**
	 * Hook into the WooCommerce woocommerce_add_to_cart_fragments filter
	 * so that the cart count is refreshed whenever items are added or removed from the cart.
	 */
	public static function cart_fragments( $fragments ) {
		$fragments['.wpex-header-cart-icon__fragments'] = self::get_extras();
		return $fragments;
	}

	/**
	 * Checks if the icon should be refreshed when adding/removing items from the cart.
	 */
	private static function maybe_add_cart_fragments() {
		$display = self::display();
		if ( 'icon_total' === $display || 'icon_count' === $display ) {
			return true;
		}
	}

	/**
	 * Return current cart count.
	 */
	private static function get_cart_count() {
		if ( ! function_exists( 'WC' ) || 0 === WC()->cart->cart_contents_count ) {
			return;
		}
		$class = 'wpex-header-cart-icon__count';
		if ( get_theme_mod( 'wpex_woo_menu_icon_bubble', true ) ) {
			$class .= ' wpex-header-cart-icon__count--bubble wpex-bg-accent wpex-rounded-full wpex-flex wpex-items-center wpex-justify-center';
		}
		$html = '<span class="' . esc_attr( $class ) . '">';
			$html .= '<span class="wpex-header-cart-icon__count-number">' . WC()->cart->cart_contents_count ?: '0';
		$html .= '</span></span>';
		return $html;
	}

	/**
	 * Return current cart price.
	 */
	private static function get_cart_price() {
		if ( ! function_exists( 'WC' ) || empty( WC()->cart->get_cart_total() ) || 0 === WC()->cart->cart_contents_count ) {
			return;
		}
		$price = WC()->cart->get_cart_total();
		return '<span class="wpex-header-cart-icon__price">' . wp_kses_post( $price ) .'</span>';
	}

	/**
	 * Get display type.
	 */
	private static function display() {
		if ( null === self::$display ) {
			self::$display = get_theme_mod( 'woo_menu_icon_display' ) ?: 'icon_count';
		}
		return self::$display;
	}

	/**
	 * Get action type.
	 */
	private static function action() {
		if ( null === self::$action ) {
			$action = '';
			if ( function_exists( 'wpex_header_menu_cart_style' ) ) {
				$action = wpex_header_menu_cart_style();
			}
			$action = $action ?: 'drop_down';
			self::$action = $action;
		}
		return self::$action;
	}

}