/**
 * search
 * @Author: sefon 2016-7-12 16:31:56
 */

'use strict';
const utils = '../../../utils';
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const redis = global.yoho.redis;

const SaleApiModel = require('./sale-api');
const SearchApiModel = require('./search-api');

const HeaderModel = require('../../../doraemon/models/header');
const productProcess = require(`${utils}/product-process-simple`);
const searchHandler = require('./search-handler');
const hotBrandsModel = require('../../../doraemon/models/hot-brands');
const _ = require('lodash');
const Fn = require('lodash/fp');
const md5 = require('md5');
const cache = global.yoho.cache;
const config = global.yoho.config;
const logger = global.yoho.logger;

const needParams = ['query', 'msort', 'misort'];

const CACHE_TIME_S = 60;

function _getCacheKey(params, page) {
    let sortByKey = Fn.pipe(Fn.toPairs, Fn.sortBy(0), Fn.flatten);
    let genKey = Fn.pipe(Fn.cloneDeep, sortByKey, Fn.join('_'));

    return `render_cache_${page}_${md5(genKey(params))}`;
}

function getKeyActivity(query) {
    return this.searchApi.getKeyActivityAsync(query).then(result => {
        return _.get(result, 'data.urlobj.pcUrl', '');
    });
}

const _setSearchData = (result, params, channel) => {
    let changeQuery = Object.assign({}, params);
    let finalResult = {
        headerData: Object.assign(result[0].headerData, {
            header: true
        }),
        search: {}
    };

    // 获取左侧类目数据
    if (result[1].code === 200) {
        let dps = {};

        _.forEach(needParams, (value) => {
            if (params[value]) {
                dps[value] = params[value];
            }
        });

        finalResult.search = {
            leftContent: searchHandler.handleSortData(result[1].data, dps, params),
            isSearch: true
        };
    }

    // 获取商品数据和顶部筛选条件
    if (result[2].code === 200) {

        // 搜索推荐词,获取对应的参数值
        let termsSuggestion = _.get(result[2], 'data.suggestion.terms_suggestion', []);

        // 推荐词 获取无商品,首次搜索,通过isChangedQuery做开关
        if (result[2].data.isChangedQuery === 'Y') {
            Object.assign(changeQuery, {query: termsSuggestion[0]});
        }

        let filters = Object.assign(searchHandler.handleFilterDataAll(result[2].data, changeQuery),
            _.get(finalResult, 'search.leftContent.sort', {}));

        filters.checkedConditions.conditions = _.concat(filters.checkedConditions.conditions,
            _.get(finalResult, 'search.leftContent.checked', []));

        Object.assign(finalResult.search,
            searchHandler.handlePathNavData({total: result[2].data.total}, params, 'search', channel),
            {
                filters: filters,
                opts: searchHandler.handleOptsData(changeQuery, result[2].data.total, result[2].data.filter),
                totalCount: result[2].data.total,
                footPager: searchHandler.handlePagerData(result[2].data.total, changeQuery),
                goods: productProcess.processProductList(result[2].data.product_list,
                    Object.assign({showDiscount: false, from: {type: 'search', params: params}}, params)),
                latestWalk: 6,
                hasNextPage: searchHandler.handleNextPage(changeQuery, result[2].data.total),
                shopEntry: result[3],
                name: params.query,
                suggest: (termsSuggestion.length !== 0) ? termsSuggestion.slice(0, 3) : false,
                changedQuery: result[2].data.isChangedQuery === 'Y',
                suggestFirst: finalResult.search.suggestFirst,
                suggestSecond: finalResult.search.suggestSecond
            });

        if (finalResult.search.changedQuery) {

            finalResult.search.suggestFirst = finalResult.search.suggest[0];
            finalResult.search.suggestSecond = _.slice(termsSuggestion, 1, termsSuggestion.length).splice(0, 3);
        }

        finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))};
    }
    return finalResult;
};

/**
 * 转换价格
 *
 * @param float|string $price 价格
 * @return float|string 转换之后的价格
 */
const _transPrice = (price) => {
    return price ? (price * 1).toFixed(2) : '0.00';
};

/**
 * 获取搜索数据
 * @param  {[type]} origin [description]
 * @return {[type]}        [description]
 */
function getSearchData(params, channel) {
    let searchParams = searchHandler.getSearchParams(params);

    switch (channel) {
        case 'boys':
            searchParams.physical_channel = 1;
            break;
        case 'girls':
            searchParams.physical_channel = 2;
            break;
        case 'kids':
            searchParams.physical_channel = 3;
            break;
        case 'lifestyle':
            searchParams.physical_channel = 4;
            break;
        default:
            break;
    }

    // 调用接口
    let apiMethod = [
        this.headerModel.requestHeaderData(channel),
        this.searchApi.getSortList(Object.assign({}, searchParams, {msort: '', misort: '', sort: ''})),
        this.searchApi.getProductList(searchParams, 'fuzzySearch'),
        this.searchApi.getShopList(params)
    ];

    return Promise.all(apiMethod).then(result => {
        if (_.get(result, '[2].data.isChangedQuery', '') === 'Y') {
            return this.searchApi.getSortList(Object.assign({}, searchParams, {
                msort: '',
                query: _.get(result, '[2]data.suggestion.terms_suggestion[0]', ''),
                misort: '', sort: ''
            })).then(subRes => {
                result[1] = subRes;

                return _setSearchData(result, params, channel);
            });
        }

        return _setSearchData(result, params, channel);
    });
}

function getSearchDataPre(params, channel) {
    let cKey = _getCacheKey(Object.assign({channel: channel}, params), 'search');
    let getOriginData = () => {
        return this.getSearchData(params, channel).then(result => {

            // 查询结果为空则不cache
            if (config.useCache && !_.isEmpty(_.get(result, 'search.goods', []))) {
                cache.set(cKey, result, CACHE_TIME_S)
                    .catch(err => logger.debug(`search render cache data save fail:${err.toString()}`));
            }

            return result;
        });
    };

    if (config.useCache) {
        return cache.get(cKey).catch(err => {
            logger.debug(`get search render cache data fail:${err.toString()}`);

            return getOriginData();
        }).then(cdata => {
            let hasCache = false;

            if (cdata) {
                try {
                    cdata = JSON.parse(cdata);
                    hasCache = true;
                } catch (e) {
                    logger.debug('search render cache data parse fail.');
                }
            }

            if (hasCache) {
                return cdata;
            } else {
                return getOriginData();
            }
        });
    }

    return getOriginData();
}

/**
 * 搜索提示
 */
function getSuggest(params) {
    return this.searchApi.getSuggest(params).then(result => {
        let dest = [];

        if (result.code === 200) {
            dest = searchHandler.handleSuggest(result.data);
        }

        return dest;
    });
}

function getListBrandsFilter(params, nparams) {
    return this.searchApi.getBrands4Filter(Object.assign({}, params, nparams)).then(result => {
        let dest = [];

        if (result.code === 200) {
            dest = searchHandler.handleFilterBrands(result.data, params);
        }

        return dest;
    });
}

function getBrands4Filter(params) {

    let nparams = {};

    if (params && params.price) {
        let mp = params.price.split(',');
        let nmp = [];

        nmp[0] = (mp && mp[0]) || 0;
        nmp[1] = (mp && mp[1]) || 99999;
        nparams.price = nmp.join(',');
    }

    if (params && params.from) {
        nparams.from = params.from;
        delete params.from;
    }

    // 生成路径包含callback 导致多次调用多个 callback问题
    if (params && params.callback) {
        delete params.callback;
    }

    const specialId = parseInt(`0${params.specialsale_id || ''}`, 10);

    if (specialId) {
        return this.saleApi.getSaleSpecialAsync(specialId).then(special => {
            if (special && special.data) {
                let data = special.data;

                // 传品牌ID参数
                if (data.brand_id) {
                    nparams.brand = data.brand_id;
                }

                // 传促销id,促销id为空时传专区id
                if (data.ispromotion) {
                    nparams.promotion = data.ispromotion;
                }
            }

            return this.getListBrandsFilter(params, nparams);
        });
    }

    // 商品详情页促销跳转
    if (params && params.psp_id) {
        Object.assign(nparams, {
            promotion_id: params.psp_id,
            method: 'app.promotion.aggBrand'
        });
    }

    // 优惠券商品列表
    if (params && params.cpc_id && params.coupon_code) {
        Object.assign(nparams, {
            coupon_id: params.cpc_id,
            coupon_code: params.coupon_code,
            method: 'app.coupon.aggBrand'
        });
    }

    return this.getListBrandsFilter(params, nparams);
}


/**
 * 搜索少或无 可能喜欢
 * @param int $page 分页页码

 * @return array

 * */
function getSearchLessProduct(channelNum, uid, udid, page) {
    return co(function* () {

        let result = {

            code: 200,
            message: '',
            data: {

                header: '可能喜欢的商品',
                hasPrev: false,
                hasNext: false,
                item: null

            }
        };

        if (!_.isNumber(page)) {
            return result;
        }

        let together = yield this.searchApi.lessRecommend(channelNum, uid, udid, '100003', 20);

        if (page > 5) {
            page = 1;
        }

        if (!_.get(together, 'data.product_list')) {
            return result;
        }

        result.data.hasPrev = true;
        result.data.hasNext = true;

        result.data.item = _.map(together.data.product_list, it => {

            let item = {
                id: it.product_id,
                skn: it.product_skn,
                title: it.product_name,
                img: it.default_images ? helpers.image(it.default_images, 180, 240) : '',
                alt: it.product_name,
                price: '¥' + _transPrice(it.sales_price),
                marketPrice: _transPrice(it.market_price) <= _transPrice(it.sales_price) ?
                    false : ('¥' + _transPrice(it.market_price))
            };

            item.href = helpers.getUrlBySkc(it.product_skn);

            return item;

        });


        // 当数据量不足6个时,判定为没有下一页

        if (page === 1) {
            result.data.hasPrev = false;
        }

        if (!result.data.item || result.data.item.length < 6) {
            result.data.hasNext = false;
        }

        return result;

    }).bind(this)();

}

const _setSearchKeywordData = (result, params, channel) => {
    let changeQuery = Object.assign({}, params);
    let finalResult = {
        headerData: Object.assign(result[0].headerData, {
            header: true
        }),
        search: {}
    };

    _.unset(changeQuery, 'query');

    // 获取左侧类目数据
    if (result[1].code === 200) {

        finalResult.search = {
            leftContent: searchHandler.handleSuggestData(_.get(result, '[1].data', []), params.query),
            isSearch: true
        };
    }

    // 获取商品数据和顶部筛选条件
    if (result[2].code === 200) {
        Object.assign(finalResult.search,
            searchHandler.handlePathNavData({total: result[2].data.total}, params, 'search', channel),
            {
                opts: searchHandler.handleOptsData(changeQuery, result[2].data.total),
                totalCount: result[2].data.total,
                footPager: searchHandler.handlePagerData(result[2].data.total, changeQuery),
                goods: productProcess.processProductList(result[2].data.product_list,
                    Object.assign({showDiscount: false, from: {type: 'search', params: params}}, params)),
                latestWalk: 6,
                hasNextPage: searchHandler.handleNextPage(changeQuery, result[2].data.total),
                name: params.query
            });

        finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))};
    }
    return finalResult;
};

/**
 * 获取搜索建议数据
 * @param  {[type]} origin [description]
 * @return {[type]}        [description]
 */
function getSearchKeywordData(params, channel) {
    let searchParams = searchHandler.getSearchParams(params);

    switch (channel) {
        case 'boys':
            searchParams.physical_channel = 1;
            break;
        case 'girls':
            searchParams.physical_channel = 2;
            break;
        case 'kids':
            searchParams.physical_channel = 3;
            break;
        case 'lifestyle':
            searchParams.physical_channel = 4;
            break;
        default:
            break;
    }

    searchParams.need_filter = 'no';

    // 调用接口
    let apiMethod = [
        this.headerModel.requestHeaderData(channel),
        this.searchApi.getSuggest({keyword: searchParams.query.substring(0, 2)}),
        this.searchApi.getSeoProductList(searchParams, 'fuzzySearch')
    ];

    return Promise.all(apiMethod).then(result => {

        return _setSearchKeywordData(result, params, channel);
    });
}

/**
 * 获取搜索建议数据
 * @id  {[number]} origin [description]
 * @param  {[object]} origin [description]
 * @channel  {[string]} origin [description]
 * @return {[object]}        [description]
 */
function getSearchKeywordDataById(id, params, channel) {
    return co(function* () {
        let redisData = yield redis.all([
            ['get', `global:yoho:seo:keywords:id:${id}`]
        ]);

        if (!redisData[0]) {
            return false;
        }

        redisData = JSON.parse(redisData[0]);

        params.query = redisData.name;

        let resData = yield this.getSearchKeywordData(params, channel);

        resData.queryKey = params.query;

        if (!_.isEmpty(redisData.data)) {
            _.forEach(redisData.data, value => {
                if (!value) {
                    return;
                }

                let href = helpers.urlFormat(`/chanpin/${value.id}.html`, null, 'www');

                Object.assign(value, {
                    name: value.keyword,
                    href: href,
                    url: href
                });
            });

            let rarr = _.chunk(redisData.data, 12);

            if (rarr.length) {
                _.set(resData, 'search.leftContent.allSuggest.list', rarr.shift());
                _.set(resData, 'recommendKeywordsInfo', {
                    recommendKeywordsTitle: '更多推荐',
                    recommendKeywords: _.concat(...rarr)
                });
            }
        }

        // 前10的热销品牌
        Object.assign(resData.search.leftContent, searchHandler.hotBrands(hotBrandsModel.hotBrands().slice(0, 10)));

        return resData;
    }).bind(this)();
}


module.exports = class extends global.yoho.BaseModel {
    constructor(ctx) {
        super(ctx);

        this.searchApi = new SearchApiModel(ctx);
        this.saleApi = new SaleApiModel(ctx);
        this.headerModel = new HeaderModel(ctx);

        this.getKeyActivity = getKeyActivity.bind(this);
        this.getSearchData = getSearchData.bind(this);
        this.getSearchDataPre = getSearchDataPre.bind(this);
        this.getSuggest = getSuggest.bind(this);
        this.getListBrandsFilter = getListBrandsFilter.bind(this);
        this.getBrands4Filter = getBrands4Filter.bind(this);
        this.getSearchLessProduct = getSearchLessProduct.bind(this);
        this.getSearchKeywordData = getSearchKeywordData.bind(this);
        this.getSearchKeywordDataById = getSearchKeywordDataById.bind(this);
    }
};