from logging import getLogger

from intranet.search.abovemeta.request import Request

from .base import HttpStep, ParallelStep, api_urls, timeouts

log = getLogger(__name__)


class OneFacetStep(HttpStep):
    FACET_VALUES_LIMIT = 100

    def __init__(self, facet_name, facet_value, revision, *args, **kwargs):
        self.revision = revision
        self.facet_name = facet_name
        self.facet_value = facet_value
        super().__init__(*args, **kwargs)

    def get_request(self, state):
        sorted_values = [v['value'] for v in sorted(self.facet_value.values(),
                                                    key=lambda a: a['doccount'],
                                                    reverse=True)]
        query = {
            'revision': self.revision,
            'user': state.user,
            'language': state.language,
            'name': self.facet_name,
            # вытаскиваем не все фасеты, а только определенное количество самых популярных
            'values': sorted_values[:self.FACET_VALUES_LIMIT],
            'request_id': state.request_id,
        }
        endpoint = api_urls['labels']
        return Request(
            url=endpoint.url(query=query),
            type_='api',
            name='facets_labels',
            headers=endpoint.get('headers', {}),
            request_timeout=timeouts['labels'],
            retries=1,
        )

    def set_data(self, state, data):
        facet_data = data.get(self.facet_name, {})

        cur_facets = state.searches['search_results']['facets'][self.facet_name]

        for value, info in facet_data.items():
            if value in cur_facets:
                cur_facets[value].update(info)


class FacetsStep(ParallelStep):
    def get_steps(self, state=None):
        result = []
        current_search = state.searches.get('search_results', {})

        if not current_search or 'facets' not in current_search:
            return result

        for name, value in current_search['facets'].items():
            for revision in current_search['search_settings']['revisions']:
                result.append(OneFacetStep(name, value, revision['id']))

        self.steps = result

        return result

    def process_response(self, state, data):
        search = state.searches.get('search_results', {})

        if not search or 'facets' not in search:
            return

        # Проверяем, для всех ли фасетов удалось получить лейблы
        for facet_name, cur_facets in search['facets'].items():
            for key, data in cur_facets.items():
                # Если нет - то лейблом берем его value
                if not isinstance(data, dict):
                    res = {'doccount': data, 'label': key, 'value': key}
                    search['facets'][facet_name][key] = res

        # Отмечаем выбранный в запросе фасет
        for facet_name, values in state.facets.items():
            for value in values:
                if facet_name in search['facets'] and value in search['facets'][facet_name]:
                    search['facets'][facet_name][value]['selected'] = True
