const SearchBox = function (rootElement) {
    this.apiSetting = {
        'timeout': 1000,
        'url': suggestApiUrl
    }

    this.categorySuggestList = [];
    this.campaignSuggestList = [];
    this.keywordSuggestList = [];

    this.root = $(rootElement);
    this.form = this.root.find('form').eq(0);
    this.formCategory = this.form.find("[name='category']").eq(0);
    this.formSearchWord = this.form.find('.pulldown-header__input').eq(0);
    this.formClear = this.form.find('.pulldown-header__clear').eq(0);
    this.formSubmit = this.form.find('.pulldown-header__button').eq(0);
    this.suggestArea = this.root.find('.pulldown-header-suggest').eq(0);
    this.suggestAreaOverlay = this.root.find('.l-overlay-suggest').eq(0);
    this.categorySuggestArea = this.suggestArea.find('.pulldown-header-suggest__category').eq(0);
    this.campaignSuggestArea = this.suggestArea.find('.pulldown-header-suggest__campaign').eq(0);
    this.keywordSuggestArea = this.suggestArea.find('.pulldown-header-suggest__search').eq(0);
    this.templateArea = this.root.find('.pulldown-header-suggest__template').eq(0);
    this.templateSuggestCategoryItem = this.templateArea.find('.pulldown-header-suggest__category').children().eq(0);
    this.templateSuggestCampaignItem = this.templateArea.find('.pulldown-header-suggest__campaign').children().eq(0);
    this.templateSuggestKeywordItem = this.templateArea.find('.pulldown-header-suggest__keyword').children().eq(0);

    this.inputText = '';
    this.selectedCategory = this.formCategory.val();

    this.formSearchWord.on('input', this.handleChangeEvent.bind(this));
    this.formSearchWord.on('keyup', this.handleChangeEvent.bind(this));
    this.formSearchWord.on('focus', this.handleChangeEvent.bind(this));
    this.formClear.on('click', this.handleClearEvent.bind(this));
    this.formCategory.on('change', this.handleChangeEvent.bind(this));
    this.formSubmit.on('click', this.handleSearchEvent.bind(this));
    $(window).on('keydown', this.handleKeyUpDownEvent.bind(this));
    $(document).on('click', function (e) {
        if (!$(e.target.closest('form')).is(this.form) || $(e.target.closest('.l-overlay-suggest')).is(this.suggestAreaOverlay)) {
            this.hideSuggestArea();
        }
    }.bind(this));
}

SearchBox.prototype.lookup = function (obj, path) {
    const keys = path.split('.');

    for (let k in keys) {

        const key = keys[k];

        if (!obj.hasOwnProperty(key)) {
            return false;
        }

        if (keys.length > 1) {
            return this.lookup(obj[key], keys.splice(1).join('.'));
        }

        return true;
    }
}

SearchBox.prototype.setCategory = function (category) {
    this.selectedCategory = category;
    this.formCategory.val(category);
    this.getSuggest(this.inputText, this.selectedCategory, false);
}

SearchBox.prototype.getCategory = function () {
    return this.formCategory.val();
}

SearchBox.prototype.setSearchWord = function (word) {
    word = word.trim();

    if (word === '') {
        this.formClear.removeClass('is-active');
    } else {
        this.formClear.addClass('is-active');
    }

    this.inputText = word;
    this.formSearchWord.val(word);
    this.getSuggest(this.inputText, this.selectedCategory, false);
}

SearchBox.prototype.getSearchWord = function () {
    return this.formSearchWord.val();
};

SearchBox.prototype.showSuggestArea = function () {
    this.suggestArea.addClass('is-active');
    this.suggestAreaOverlay.addClass('is-active');
}

SearchBox.prototype.hideSuggestArea = function () {
    this.suggestArea.removeClass('is-active');
    this.suggestAreaOverlay.removeClass('is-active');
}

SearchBox.prototype.isSuggestAreaOpen = function () {
    return this.suggestArea.hasClass('is-active');
}

SearchBox.prototype.activateSuggest = function () {
    this.suggestArea.find('button').remove();

    if (this.categorySuggestList.length === 0 && this.campaignSuggestList.length === 0 && this.keywordSuggestList.length === 0) {
        this.hideSuggestArea();
        return;
    }

    if (this.categorySuggestList.length === 0) {
        this.categorySuggestArea.find('.pulldown-header-suggest__category-title').hide();
    } else {
        this.categorySuggestArea.find('.pulldown-header-suggest__category-title').show();

        const categorySuggestArea = this.categorySuggestArea;
        const categorySuggestTmpl = this.templateSuggestCategoryItem;
        const categoryClickEvent = this.handleClickSuggestCategoryEvent.bind(this);

        $.each(this.categorySuggestList, function (index, value) {

            const clone = categorySuggestTmpl.clone(true);

            clone.find('.pulldown-header-suggest__item-title').text(value['direct_category_name'].replace(/\|/g, ' > '));
            clone.attr('data-ids', value['direct_category_id']);
            clone.addClass('js-suggest-focus-target');
            clone.click(categoryClickEvent);
            categorySuggestArea.append(clone);
        });
    }

    if (this.campaignSuggestList.length === 0) {
        this.campaignSuggestArea.find('.pulldown-header-suggest__campaign-title').hide();
    } else {
        this.campaignSuggestArea.find('.pulldown-header-suggest__campaign-title').show();

        const campaignSuggestArea = this.campaignSuggestArea;
        const campaignSuggestTmpl = this.templateSuggestCampaignItem;
        const campaignClickEvent = this.handleClickSuggestCampaignEvent.bind(this);

        $.each(this.campaignSuggestList, function (index, value) {

            const clone = campaignSuggestTmpl.clone(true);

            clone.find('.pulldown-header-suggest__item-title').text(value['direct_campaign_name']);
            clone.attr('data-url', value['direct_campaign_id']);
            clone.addClass('js-suggest-focus-target');
            clone.click(campaignClickEvent);
            campaignSuggestArea.append(clone);
        });
    }

    const keywordSuggestArea = this.keywordSuggestArea;
    const keywordSuggestTmpl = this.templateSuggestKeywordItem;
    const keywordClickEvent = this.handleClickSuggestWordEvent.bind(this);

    $.each(this.keywordSuggestList, function (index, value) {

        const clone = keywordSuggestTmpl.clone(true);

        clone.find('.pulldown-header-suggest__item-title').text(value['word']);
        clone.addClass('js-suggest-focus-target');
        clone.click(keywordClickEvent);
        keywordSuggestArea.append(clone);
    });

    this.showSuggestArea();
}

SearchBox.prototype.getSuggest = function (word, path, activate) {
    if (typeof activate === 'undefined') {
        activate = true;
    }

    if (word === '') {
        this.categorySuggestList = [];
        this.keywordSuggestList = [];
        this.campaignSuggestList = [];
        this.activateSuggest();
        return;
    }

    const params = {
        'kw': word,
        'rows': 15,
        'dr_category': 3,
        'dr_campaign': 2,
        'wt': "jsonp",
    }

    if (path !== 'all') {
        params.fq_category = path;
    }

    $.ajax({
        url: this.apiSetting.url,
        type: 'GET',
        data: params,
        timeout: this.apiSetting.timeout,
        dataType: 'jsonp',
        cache: false, // IE11対策
        jsonp: 'cbk',
        jsonpCallback: function () {
            return 'callback' + Math.random().toString(32).substring(2);
        },
        headers: {'Accept-Encoding': 'gzip'}
    }).done(function (data) {

        if (word === this.formSearchWord.val().trim()) {

            if (this.lookup(data, 'response.keyword.docs.item') && data['response']['keyword']['docs']['item'].length > 0) {
                this.keywordSuggestList = data['response']['keyword']['docs']['item'];
            } else {
                this.keywordSuggestList = [];
            }

            if (this.lookup(data, 'response.category.docs.item') && data['response']['category']['docs']['item'].length > 0) {
                this.categorySuggestList = data['response']['category']['docs']['item'];
            } else {
                this.categorySuggestList = [];
            }

            if (this.lookup(data, 'response.campaign.docs.item') && data['response']['campaign']['docs']['item'].length > 0) {
                this.campaignSuggestList = data['response']['campaign']['docs']['item'];
            } else {
                this.campaignSuggestList = [];
            }

            if (activate) {
                this.activateSuggest();
            }
        }

    }.bind(this));
}

SearchBox.prototype.handleChangeEvent = function (e) {
    const newText = this.formSearchWord.val().trim();
    const newCategory = this.formCategory.val();

    if (e.key === 'Enter' || e.key === 'Escape' || e.key === 'Esc') {
        return false;
    }

    if (this.inputText === newText && this.selectedCategory === newCategory) {
        this.activateSuggest();
        return;
    }

    this.inputText = newText;
    this.selectedCategory = newCategory;

    if (this.inputText === '') {
        this.formClear.removeClass('is-active');
        this.categorySuggestList = [];
        this.campaignSuggestList = [];
        this.keywordSuggestList = [];
        this.activateSuggest();
        return;
    }

    this.formClear.addClass('is-active');

    this.getSuggest(this.inputText, this.selectedCategory);
}

SearchBox.prototype.handleClearEvent = function (e) {
    this.formSearchWord.val('');
    this.formSearchWord.trigger('keyup');
}

SearchBox.prototype.handleClickSuggestCategoryEvent = function (e) {
    const ids = $(e.currentTarget).attr('data-ids').split('|');
    let url = '/category/';
    let diff = '';
    let id = '';

    ids.forEach(function (value, index, array) {
        id = value.replace(new RegExp('^' + diff), '');
        url = url + id + '/';
        diff = diff + id;
    });

    this.hideSuggestArea();
    window.location.href = url;
}

SearchBox.prototype.handleClickSuggestCampaignEvent = function (e) {
    this.hideSuggestArea();
    window.location.href = $(e.currentTarget).attr('data-url');
}

SearchBox.prototype.handleClickSuggestWordEvent = function (e) {
    const word = $(e.currentTarget).find('.pulldown-header-suggest__item-title').text();

    this.formSearchWord.val(word);
    this.formSubmit.trigger('click');
}

SearchBox.prototype.handleSearchEvent = function (e) {
    let word = this.formSearchWord.val().trim();
    let action = '';
    let querySting = '';

    if (word !== '') {
        word = word.replace('+', '＋');
        word = word.split('/').join(' ');
        action = '/search/' + encodeURIComponent(word) + '/';
        querySting = this.form.serialize();

        this.hideSuggestArea();
        window.location.href = action + '?' + querySting;
    }
}

SearchBox.prototype.handleKeyUpDownEvent = function (e) {
    if (this.isSuggestAreaOpen()) {
        if (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'Up' || e.key === 'Down') {
            let focuses = this.root.find('.js-suggest-focus-target');
            let currentFocusIndex = focuses.index($(':focus'));

            if (currentFocusIndex > -1) {
                if (focuses.eq(currentFocusIndex).is(':button')) {
                    focuses.eq(currentFocusIndex).css('font-weight', 'normal');
                    focuses.eq(currentFocusIndex).css('background-color', '#FFFFFF');
                }

                if (e.key === 'ArrowUp' || e.key === 'Up') { // ↑
                    --currentFocusIndex;
                    currentFocusIndex = currentFocusIndex < 0 ? focuses.length - 1 : currentFocusIndex;
                } else if (e.key === 'ArrowDown' || e.key === 'Down') { // ↓
                    ++currentFocusIndex;
                    currentFocusIndex = currentFocusIndex >= focuses.length ? 0 : currentFocusIndex;
                }

                focuses.eq(currentFocusIndex).focus();

                if (focuses.eq(currentFocusIndex).is(':button')) {
                    focuses.eq(currentFocusIndex).css('font-weight', 'bold');
                    focuses.eq(currentFocusIndex).css('background-color', '#F5F5F5');
                }

                if (focuses.eq(currentFocusIndex).hasClass('pulldown-header-suggest__search-button')) {
                    const word = focuses.eq(currentFocusIndex).find('.pulldown-header-suggest__item-title').text();

                    this.inputText = word;
                    this.formSearchWord.val(word);
                }
            }

            return false;
        } else if (e.key === 'Escape' || e.key === 'Esc') {
            this.hideSuggestArea();
            return false;
        } else if (e.key === 'Enter') {
            let currentFocusElement = this.root.find(':focus');

            if (currentFocusElement.length !== 0) {

                if (currentFocusElement.is('.pulldown-header__input')) {
                    this.formSubmit.trigger('click');
                } else if (currentFocusElement.is('.pulldown-header-suggest__category-button')) {
                    currentFocusElement.trigger('click');
                } else if (currentFocusElement.is('.pulldown-header-suggest__campaign-button')) {
                    currentFocusElement.trigger('click');
                } else if (currentFocusElement.is('.pulldown-header-suggest__search-button')) {
                    currentFocusElement.trigger('click');
                }

                return false;
            }
        } else {
            this.formSearchWord.focus();
        }
    } else if (e.key === 'Enter' && this.formSearchWord.is(':focus')) {
        this.formSubmit.trigger('click');
        return false;
    }
}