<?php

namespace Hura8\Components\Product\Controller;

use Hura8\System\Url;


class ProductFilterOptionsTranslationController {

    protected $_request_url = '';
    protected $_url_elements = [
        'scheme' => '',
        'host' => '',
        'port' => '',
        'user' => '',
        'pass' => '',
        'path' => '',
        'query' => [],
        'fragment' => '',
    ];

    protected $_price_format = '';
    protected $_brand_format = '';
    protected $_filter_format = '';


    public function __construct($request_url) {
        if(defined('PRICE_FILTER_FORMAT') && PRICE_FILTER_FORMAT) {
            $this->_price_format = PRICE_FILTER_FORMAT;
        }

        if(defined('BRAND_FILTER_FORMAT') && BRAND_FILTER_FORMAT) {
            $this->_brand_format = BRAND_FILTER_FORMAT;
        }

        if(defined('ATTRIBUTE_FILTER_FORMAT') && ATTRIBUTE_FILTER_FORMAT ) {
            $this->_filter_format = ATTRIBUTE_FILTER_FORMAT;
        }

        $this->_request_url = $request_url;
        $this->_url_elements = Url::parse($request_url);
    }


    public function getAllFilterOptions(array $category_list = [], array $attribute_list = [], array $brand_list = [], array $price_list_options = []) {

        $result = [
            'category'  => $category_list,
            'price'     => $this->translatePriceList($price_list_options),
            'brand'     => $this->translateBrandList($brand_list),
            'attribute' => $this->translateAttributeList($attribute_list),
        ];

        $selected_categories = array_filter($category_list, function ($item){ return $item['is_selected'];});
        $selected_prices = array_filter($result['price'], function ($item){ return $item['is_selected'];});
        $selected_brands = array_filter($result['brand'], function ($item){ return $item['is_selected'];});
        $selected_attributes = array_filter($result['attribute'], function ($item){ return $item['is_selected'];});

        $filter_messages = [];

        foreach ($selected_categories as $selected_category) {
            $filter_messages[] = [
                'name' => $selected_category['name'], // 'Danh mục: '.
                'reset_url' => Url::buildUrl($this->_request_url, ['category' => ''] ),
            ];
        }

        foreach ($selected_prices as $selected_price) {
            $filter_messages[] = [
                'name' => $selected_price['name'], // 'Giá: '.
                'reset_url' => $selected_price['url'],
            ];
        }

        foreach ($selected_brands as $selected_brand) {
            $filter_messages[] = [
                'name' => $selected_brand['name'], // 'Thương hiệu: '.
                'reset_url' => $selected_brand['url'],
            ];
        }

        foreach ($selected_attributes as $selected_attribute) {

            $selected_attribute_values = array_filter($selected_attribute['value_list'], function ($item){ return $item['is_selected'];});

            foreach ($selected_attribute_values as $selected_attribute_value) {
                $filter_messages[] = [
                    'name'      => $selected_attribute_value['name'], //$selected_attribute['name'].': '.$selected_attribute_value['name'],
                    'reset_url' => $selected_attribute_value['url'],
                ];
            }
        }


        return [$result, $filter_messages];
    }


    public function translateAttributeList(array $attribute_list = []) {
        $result = [];

        foreach ($attribute_list as $attr_info) {
            $copy = $attr_info;
            $copy['value_list'] = array_map(function ($value_info) use ($attr_info) {
                return $this->translateAttributeValue($attr_info['filter_code'], $value_info);
            }, $attr_info['value_list']);

            $result[] = $copy;
        }

        return $result;
    }


    protected function translateAttributeValue($attribute_filter_code, array $value_info = []) {
        $copy = $value_info;

        if($copy['is_selected']) {
            $copy['url'] =  Url::buildUrl($this->_request_url, $this->buildAttributeValueUrlResetParameters($attribute_filter_code, $value_info['id'], $value_info['api_key']) );
        }else{
            $copy['url'] = Url::buildUrl($this->_request_url, $this->buildAttributeValueUrlParameters($attribute_filter_code, $value_info['id'], $value_info['api_key']) );
        }

        //$copy['reset_url']  = Url::buildUrl($this->_request_url, $this->buildAttributeValueUrlResetParameters($attribute_filter_code, $value_info['id'], $value_info['api_key']) );

        return $copy;
    }


    protected function buildAttributeValueUrlParameters($attribute_filter_code, $value_id, $value_api_key) {
        if($this->_filter_format == 'filter_code') {
            $filter_query          = (isset($this->_url_elements['query'][$attribute_filter_code])) ? $this->_url_elements['query'][$attribute_filter_code] : '';
            $filter_value_list     = ($filter_query) ? explode(FILTER_VALUE_SEPARATOR, $filter_query) : [];

            $filter_value_list[] = $value_api_key;

            $result = [];
            $result[$attribute_filter_code] = join(FILTER_VALUE_SEPARATOR, $filter_value_list );

            return $result;
        }

        // default
        $filter_query          = (isset($this->_url_elements['query']['filter'])) ? $this->_url_elements['query']['filter'] : '';
        $filter_value_list     = ($filter_query) ? explode(FILTER_VALUE_SEPARATOR, $filter_query) : [];

        $filter_value_list[] = $value_id;
        sort($filter_value_list);

        return [
            'filter' => join(FILTER_VALUE_SEPARATOR, $filter_value_list ),
        ];
    }


    protected function buildAttributeValueUrlResetParameters($attribute_filter_code, $value_id, $value_api_key) {
        if($this->_filter_format == 'filter_code') {
            $filter_query          = (isset($this->_url_elements['query'][$attribute_filter_code])) ? $this->_url_elements['query'][$attribute_filter_code] : '';
            $filter_value_list     = ($filter_query) ? explode(FILTER_VALUE_SEPARATOR, $filter_query) : [];

            $filter_value_list = remove_item_from_array($filter_value_list, $value_api_key);

            $result = [];
            $result[$attribute_filter_code] = join(FILTER_VALUE_SEPARATOR, $filter_value_list );

            return $result;
        }


        // default
        $filter_query    = (isset($this->_url_elements['query']['filter'])) ? $this->_url_elements['query']['filter'] : '';
        $filter_value_list     = ($filter_query) ? explode(FILTER_VALUE_SEPARATOR, $filter_query) : [];

        $filter_value_list = remove_item_from_array($filter_value_list, $value_id);

        return [
            'filter' => join(FILTER_VALUE_SEPARATOR, $filter_value_list ),
        ];
    }


    public function translateBrandList(array $brand_list = []) {

        return array_map(function ($item){
            $copy = $item;

            if(($copy['is_selected'])) {
                $copy['url']  = Url::buildUrl($this->_request_url, $this->buildBrandUrlResetParameters($item['id'], $item['brand_index']) ) ;
            }else{
                $copy['url']  = Url::buildUrl($this->_request_url, $this->buildBrandUrlParameters($item['id'], $item['brand_index']) );
            }

            //$copy['reset_url']  = Url::buildUrl($this->_request_url, $this->buildBrandUrlResetParameters($item['id'], $item['brand_index']) );
            //unset($copy['brand_index']);

            return $copy;

        }, $brand_list);

    }


    protected function buildBrandUrlResetParameters($brand_id, $brand_index){
        $brand_query    = (isset($this->_url_elements['query']['brand'])) ? $this->_url_elements['query']['brand'] : '';
        $brand_list     = ($brand_query) ? explode(FILTER_VALUE_SEPARATOR, $brand_query) : [];

        if($this->_brand_format == 'brand_index') {
            $brand_list = remove_item_from_array($brand_list, $brand_index);
        }else{
            $brand_list = remove_item_from_array($brand_list, $brand_id);
        }

        return [
            'brand' => join(FILTER_VALUE_SEPARATOR, $brand_list ),
        ];
    }


    protected function buildBrandUrlParameters($brand_id, $brand_index){
        $brand_query    = (isset($this->_url_elements['query']['brand'])) ? $this->_url_elements['query']['brand'] : '';
        $brand_list     = ($brand_query) ? explode(FILTER_VALUE_SEPARATOR, $brand_query) : [];

        if($this->_brand_format == 'brand_index') {
            if(!in_array($brand_index, $brand_list)) $brand_list[] = $brand_index;
        }else{
            if(!in_array($brand_id, $brand_list)) $brand_list[] = $brand_id;
        }

        return [
            'brand' => join(FILTER_VALUE_SEPARATOR, $brand_list ),
        ];
    }


    public function translatePriceList(array $price_list_options = []) {

        return array_map(function ($item){
            $copy = $item;

            $format = $this->buildPriceRangeFormat($item['min'], $item['max']);

            $copy['name']       = $format['name'];
            $copy['url']        = ($copy['is_selected']) ? Url::buildUrl($this->_request_url, $this->buildPriceUrlResetParameters()) :  Url::buildUrl($this->_request_url, $format['url_para']);

            //$copy['reset_url']  = Url::buildUrl($this->_request_url, $this->buildPriceUrlResetParameters());
            //unset($copy['min'], $copy['max']);

            return $copy;

        }, $price_list_options);

    }


    protected function buildPriceRangeFormat($min_price, $max_price) {
        if($min_price > 0 && !$max_price) {
            $title = "Trên ".$this->format_search_price($min_price);
        }elseif(!$min_price && $max_price > 0) {
            $title = "Dưới ".$this->format_search_price($max_price);
        }else{
            $title = $this->format_search_price($min_price)." - ".$this->format_search_price($max_price);
        }

        return [
            'url_para' => $this->buildPriceUrlParameters($min_price, $max_price),
            'name' => $title,
        ];
    }


    protected function format_search_price($p_price){

        $price_len = strlen($p_price);

        if($price_len < 7) {
            return round($p_price/1000,1)." ngàn";
        }
        else if($price_len < 10) {
            return round($p_price/1000000,1)." triệu";
        }

        return round($p_price/1000000000,1)." tỷ";
    }


    protected function buildPriceUrlResetParameters() {
        if( $this->_price_format == 'p') {
            return [
                "p"   =>  '',
            ];
        }

        return [
            "min"   =>  '' ,
            "max"   =>  '' ,
        ];
    }


    protected function buildPriceUrlParameters($min_price = 0, $max_price = 0) {

        if($min_price > 0 && !$max_price) {
            if( $this->_price_format == 'p') {
                return [
                    "p"   =>  "tren-".self::convertPriceFormatToFilter($this->format_search_price($min_price)),
                ];
            }

            return [
                "min"   =>  $min_price ,
            ];
        }

        if(!$min_price && $max_price > 0) {

            if( $this->_price_format == 'p') {
                return [
                    "p" => "duoi-" . self::convertPriceFormatToFilter($this->format_search_price($max_price)),
                ];
            }

            return [
                "max"   =>  $max_price,
            ];
        }

        if( $this->_price_format == 'p') {
            return [
                "p" => self::convertPriceFormatToFilter($this->format_search_price($min_price)) . "-" . self::convertPriceFormatToFilter($this->format_search_price($max_price)),
            ];
        }

        return [
            "max"   =>  $max_price ,
            "min"   =>  $min_price,
        ];
    }


    // convert: 10 ngàn  -> 10ngan, 10 triệu => 10trieu
    protected static function convertPriceFormatToFilter($price_format){
        $price_format = str_replace(['ngàn', 'triệu'], ['ngan', 'trieu'], $price_format);
        // remove whitespace
        return str_replace(" ",'', $price_format);
    }


}
