<?php
namespace OnScheduleEdgeNamespace\Modules\Shortcodes\ProductList;

use OnScheduleEdgeNamespace\Modules\Shortcodes\Lib\ShortcodeInterface;

/**
 * Class ProductList
 */
class ProductList implements ShortcodeInterface {
	/**
	* @var string
	*/
	private $base;
	
	function __construct() {
		$this->base = 'edgtf_product_list';
		
		add_action('vc_before_init', array($this,'vcMap'));
	}
	
	public function getBase() {
		return $this->base;
	}

	public function vcMap() {
		vc_map( array(
			'name' => esc_html__('Edge Product List', 'onschedule'),
			'base' => $this->base,
			'icon' => 'icon-wpb-product-list extended-custom-icon',
			'category' => esc_html__('by EDGE', 'onschedule'),
			'allowed_container_element' => 'vc_row',
			'params' => array(
					array(
						'type'       => 'dropdown',
						'param_name' => 'type',
						'heading'    => esc_html__('Type', 'onschedule'),
						'value'      => array(
							esc_html__('Standard', 'onschedule') => 'standard',
							esc_html__('Masonry', 'onschedule')  => 'masonry'
						),
						'admin_label' => true
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'info_position',
						'heading'    => esc_html__('Product Info Position', 'onschedule'),
						'value'      => array(
							esc_html__('Info On Image Hover', 'onschedule')  => 'info-on-image',
							esc_html__('Info Below Image', 'onschedule') => 'info-below-image'
						),
						'admin_label' => true
					),
					array(
						'type'       => 'textfield',
						'param_name' => 'number_of_posts',
						'heading'    => esc_html__('Number of Products', 'onschedule')
					),
                    array(
                        'type'       => 'dropdown',
                        'param_name' => 'number_of_columns',
                        'heading'    => esc_html__('Number of Columns', 'onschedule'),
                        'value'      => array(
							esc_html__('One', 'onschedule') => '1',
							esc_html__('Two', 'onschedule') => '2',
							esc_html__('Three', 'onschedule') => '3',
							esc_html__('Four', 'onschedule') => '4',
							esc_html__('Five', 'onschedule') => '5',
							esc_html__('Six', 'onschedule') => '6'
                        ),
	                    'save_always' => true
                    ),
                    array(
						'type'       => 'dropdown',
						'param_name' => 'space_between_items',
						'heading'    => esc_html__('Space Between Items', 'onschedule'),
						'value'      => array(
							esc_html__('Normal', 'onschedule') => 'normal',
							esc_html__('Small', 'onschedule') => 'small',
							esc_html__('Tiny', 'onschedule') => 'tiny',
							esc_html__('No Space', 'onschedule') => 'no'
						)
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'order_by',
						'heading'    => esc_html__('Order By', 'onschedule'),
						'value' => array(
							esc_html__('Title', 'onschedule') => 'title',
							esc_html__('Date', 'onschedule') => 'date',
							esc_html__('Random', 'onschedule') => 'rand',
							esc_html__('Post Name', 'onschedule') => 'name',
							esc_html__('ID', 'onschedule') => 'id',
							esc_html__('Menu Order', 'onschedule') => 'menu_order'
						)
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'order',
						'heading'    => esc_html__('Order', 'onschedule'),
						'value' => array(
							esc_html__('ASC', 'onschedule') => 'ASC',
							esc_html__('DESC', 'onschedule') => 'DESC'
						)
					),
					array(
	                    'type'       => 'dropdown',
	                    'param_name' => 'taxonomy_to_display',
	                    'heading'    => esc_html__('Choose Sorting Taxonomy', 'onschedule'),
	                    'value' => array(
							esc_html__('Category', 'onschedule') => 'category',
							esc_html__('Tag', 'onschedule') => 'tag',
							esc_html__('Id', 'onschedule') => 'id'
	                    ),
	                    'description' => esc_html__('If you would like to display only certain products, this is where you can select the criteria by which you would like to choose which products to display', 'onschedule')
	                ),
	                array(
	                    'type'        => 'textfield',
	                    'param_name'  => 'taxonomy_values',
	                    'heading'     => esc_html__('Enter Taxonomy Values', 'onschedule'),
	                    'description' => esc_html__('Separate values (category slugs, tags, or post IDs) with a comma', 'onschedule')
	                ),
	                array(
						'type'       => 'dropdown',
						'param_name' => 'image_size',
						'heading'    => esc_html__('Image Proportions', 'onschedule'),
						'value'      => array(
							esc_html__('Default', 'onschedule') => '',
							esc_html__('Original', 'onschedule') => 'full',
							esc_html__('Square', 'onschedule') => 'square',
							esc_html__('Landscape', 'onschedule') => 'landscape',
							esc_html__('Portrait', 'onschedule') => 'portrait',
							esc_html__('Medium', 'onschedule') => 'medium',
							esc_html__('Large', 'onschedule') => 'large'
						)
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_title',
						'heading'     => esc_html__('Display Title', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false, true)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'product_info_skin',
						'heading'    => esc_html__('Product Info Skin', 'onschedule'),
						'value'      => array(
							esc_html__('Default', 'onschedule')  => 'default',
							esc_html__('Light', 'onschedule') => 'light',
							esc_html__('Dark', 'onschedule') => 'dark'
						),
						'dependency'  => array('element' => 'info_position', 'value' => array('info-on-image')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'title_tag',
						'heading'     => esc_html__('Title Tag', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_title_tag(true)),
						'dependency'  => array('element' => 'display_title', 'value' => array('yes')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'title_transform',
						'heading'     => esc_html__('Title Text Transform', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_text_transform_array(true)),
						'dependency'  => array('element' => 'display_title', 'value' => array('yes')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_category',
						'heading'     => esc_html__('Display Category', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_excerpt',
						'heading'     => esc_html__('Display Excerpt', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'        => 'textfield',
						'param_name'  => 'excerpt_length',
						'heading'     => esc_html__('Excerpt Length', 'onschedule'),
						'description' => esc_html__('Number of characters', 'onschedule'),
						'dependency'  => array('element' => 'display_excerpt', 'value' => array('yes')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_rating',
						'heading'     => esc_html__('Display Rating', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false, true)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_price',
						'heading'     => esc_html__('Display Price', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false, true)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'        => 'dropdown',
						'param_name'  => 'display_button',
						'heading'     => esc_html__('Display Button', 'onschedule'),
						'value'       => array_flip(onschedule_edge_get_yes_no_select_array(false, true)),
						'group'	      => esc_html__('Product Info', 'onschedule')
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'button_skin',
						'heading'    => esc_html__('Button Skin', 'onschedule'),
						'value'      => array(
							esc_html__('Default', 'onschedule')  => 'default',
							esc_html__('Light', 'onschedule') => 'light',
							esc_html__('Dark', 'onschedule') => 'dark'
						),
						'dependency'  => array('element' => 'display_button', 'value' => array('yes')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'       => 'colorpicker',
						'param_name' => 'shader_background_color',
						'heading'    => esc_html__('Shader Background Color', 'onschedule'),
						'group'	     => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'       => 'dropdown',
						'param_name' => 'info_bottom_text_align',
						'heading'    => esc_html__('Product Info Text Alignment', 'onschedule'),
						'value'      => array(
							esc_html__('Default', 'onschedule')  => '',
							esc_html__('Left', 'onschedule') => 'left',
							esc_html__('Center', 'onschedule') => 'center',
							esc_html__('Right', 'onschedule') => 'right'
						),
						'dependency'  => array('element' => 'info_position', 'value' => array('info-below-image')),
						'group'	      => esc_html__('Product Info Style', 'onschedule')
					),
					array(
						'type'       => 'textfield',
						'param_name' => 'info_bottom_margin',
						'heading'    => esc_html__('Product Info Bottom Margin (px)', 'onschedule'),
						'dependency' => array('element' => 'info_position', 'value' => array('info-below-image')),
						'group'	     => esc_html__('Product Info Style', 'onschedule')
					)
				)
		) );
	}

	public function render($atts, $content = null) {
		$default_atts = array(
			'type'					  => 'standard',
			'info_position'			  => 'info-on-image',
            'number_of_posts' 		  => '8',
            'number_of_columns' 	  => '4',
            'space_between_items'	  => 'normal',
            'order_by' 				  => 'date',
            'order' 				  => 'ASC',
            'taxonomy_to_display' 	  => 'category',
            'taxonomy_values' 		  => '',
            'image_size'			  => 'full',
            'display_title' 		  => 'yes',
			'product_info_skin'       => '',
            'title_tag'				  => 'h5',
            'title_transform'		  => '',
			'display_category'        => 'no',
            'display_excerpt' 		  => 'no',
            'excerpt_length' 		  => '20',
			'display_rating' 		  => 'yes',
			'display_price' 		  => 'yes',
            'display_button' 		  => 'yes',
			'button_skin'             => 'default',
			'shader_background_color' => '',
			'info_bottom_text_align'  => '',
            'info_bottom_margin' 	  => ''
        );
		
		$params = shortcode_atts($default_atts, $atts);
		extract($params);
		
		$params['holder_classes'] = $this->getHolderClasses($params);
		$params['class_name'] = 'pli';
		
		$params['type'] = !empty($params['type']) ? $params['type'] : $default_atts['type'];
		
		$params['title_tag'] = !empty($params['title_tag']) ? $params['title_tag'] : $default_atts['title_tag'];
		$params['title_styles'] = $this->getTitleStyles($params);
		
		$params['shader_styles'] = $this->getShaderStyles($params);

		$params['text_wrapper_styles'] = $this->getTextWrapperStyles($params);

		$queryArray = $this->generateProductQueryArray($params);
		$query_result = new \WP_Query($queryArray);
		$params['query_result'] = $query_result;

		$html = onschedule_edge_get_woo_shortcode_module_template_part('templates/product-list-'.$params['type'], 'product-list', '', $params);
		
		return $html;
	}

	/**
	   * Generates holder classes
	   *
	   * @param $params
	   *
	   * @return string
	*/
	private function getHolderClasses($params){
		$holderClasses = '';

		$productListType = !empty($params['type']) ? 'edgtf-'.$params['type'].'-layout' : 'edgtf-standard-layout';

        $columnsSpace = !empty($params['space_between_items']) ? 'edgtf-'.$params['space_between_items'].'-space' : 'edgtf-normal-space';

        $columnNumber = $this->getColumnNumberClass($params);

		$infoPosition = !empty($params['info_position']) ? 'edgtf-'.$params['info_position'] : 'edgtf-info-on-image';
		
		$productInfoClasses = !empty($params['product_info_skin']) ? 'edgtf-product-info-'.$params['product_info_skin'] : '';

        $holderClasses .= $productListType . ' ' . $columnsSpace . ' ' . $columnNumber . ' ' . $infoPosition . ' ' . $productInfoClasses;
		
		return $holderClasses;
	}

    /**
     * Generates columns number classes for product list holder
     *
     * @param $params
     *
     * @return string
     */
    private function getColumnNumberClass($params){
        $columnsNumber = '';
        $columns = $params['number_of_columns'];

        switch ($columns) {
            case 1:
                $columnsNumber = 'edgtf-one-column';
                break;
            case 2:
                $columnsNumber = 'edgtf-two-columns';
                break;
            case 3:
                $columnsNumber = 'edgtf-three-columns';
                break;
            case 4:
                $columnsNumber = 'edgtf-four-columns';
                break;
            case 5:
                $columnsNumber = 'edgtf-five-columns';
                break;
            case 6:
                $columnsNumber = 'edgtf-six-columns';
                break;        
            default:
                $columnsNumber = 'edgtf-four-columns';
                break;
        }

        return $columnsNumber;
    }

	/**
	   * Generates query array
	   *
	   * @param $params
	   *
	   * @return array
	*/
	public function generateProductQueryArray($params){
		$queryArray = array(
			'post_status' => 'publish',
			'post_type' => 'product',
			'ignore_sticky_posts' => 1,
			'posts_per_page' => $params['number_of_posts'],
			'orderby' => $params['order_by'],
			'order' => $params['order'],
			'meta_query' => WC()->query->get_meta_query()
		);

        if ($params['taxonomy_to_display'] !== '' && $params['taxonomy_to_display'] === 'category') {
            $queryArray['product_cat'] = $params['taxonomy_values'];
        }

        if ($params['taxonomy_to_display'] !== '' && $params['taxonomy_to_display'] === 'tag') {
            $queryArray['product_tag'] = $params['taxonomy_values'];
        }

        if ($params['taxonomy_to_display'] !== '' && $params['taxonomy_to_display'] === 'id') {
            $idArray = $params['taxonomy_values'];
            $ids = explode(',', $idArray);
            $queryArray['post__in'] = $ids;
        }

        return $queryArray;
	}

	/**
     * Return Style for Title
     *
     * @param $params
     * @return string
     */
    public function getTitleStyles($params) {
        $styles = array();
	
	    if (!empty($params['title_transform'])) {
		    $styles[] = 'text-transform: '.$params['title_transform'];
	    }

		return implode(';', $styles);
    }

    /**
     * Return Style for Shader
     *
     * @param $params
     * @return string
     */
	public function getShaderStyles($params) {
	    $styles = array();
	
	    if (!empty($params['shader_background_color'])) {
		    $styles[] = 'background-color: '.$params['shader_background_color'];
	    }

		return implode(';', $styles);
    }

    /**
     * Return Style for Text Wrapper Holder
     *
     * @param $params
     * @return string
     */
	public function getTextWrapperStyles($params) {
	    $styles = array();
	
	    if (!empty($params['info_bottom_text_align'])) {
		    $styles[] = 'text-align: '.$params['info_bottom_text_align'];
	    }
		
        if ($params['info_bottom_margin'] !== '') {
	        $styles[] = 'margin-bottom: '.onschedule_edge_filter_px($params['info_bottom_margin']).'px';
        }

		return implode(';', $styles);
    }
}