from intranet.search.core.swarm import Indexer

import gettext
import logging
from urllib.parse import urljoin
import pycountry

from django.conf import settings
from django.utils.dateparse import parse_datetime

from intranet.search.core.sources.utils import (
    get_resource_data,
    get_document_url,
    get_short_desc,
    get_text_content,
    date_as_factor,
    normalize,
)
from intranet.search.core.utils import http

log = logging.getLogger(__name__)

rus = gettext.translation('iso3166', pycountry.LOCALES_DIR, languages=['ru'])
rus.install(unicode=True)


class Source(Indexer):
    def __init__(self, options):
        super().__init__(options)

        headers = settings.ISEARCH['api']['stat']['projects']['headers']

        self.session = http.create_session(
            headers=headers,
            verify=False,
            max_retries=3,
        )

    def get_projects(self):
        url = settings.ISEARCH['api']['stat']['projects'].url()
        projects = self.session.get(url, timeout=10)
        projects_dict = {}
        for project in projects.json():
            projects_dict[project['name']] = {
                'name': project['name'],
                'title': project['title'],
                'level': project['level'],
            }
        return projects_dict

    def get_project(self, name):
        url = settings.ISEARCH['api']['stat']['project_info'].url(query={'name': name})
        project = self.session.get(url, timeout=10)
        return {project.json()['name']: project.json()['title']}

    def do_walk(self, **kwargs):
        url = settings.ISEARCH['api']['stat']['reports'].url()
        reports = self.session.get(url, timeout=10)
        reports_list = reports.json()

        # TODO: is it right?
        if self.options['limit']:
            reports_list = reports.json()[:self.options['limit']]

        for report_name in reports_list:
            self.next('fetch', report_name=report_name)

    def do_fetch(self, report_name, **kwargs):
        url = settings.ISEARCH['api']['stat']['report_info'].url().format(name=report_name)

        report = self.session.get(url, timeout=10)
        if report.json():
            result = report.json()
            result['url'] = report_name
            self.next('create', resource=result)
        else:
            log.error('No information for %s', report_name)

    def do_create(self, resource, **kwargs):
        data = get_resource_data(resource)

        url = urljoin(get_document_url('stat'), data['url'])

        if data['ru']['last_update']:
            updated = parse_datetime(data['ru']['last_update'])
        else:
            updated = None

        doc = self.create_document(url, updated=updated)

        body = {
            'description': [get_text_content(resource['ru']['meta']['desc_wiki'] or ''),
                            get_text_content(resource['en']['meta']['desc_wiki'] or '')],
            'z_ns_hidden': {
                'name': [resource['ru']['menu']['name'], resource['en']['menu']['name']],
                'parents_names': ([p['name'] for p in resource['ru']['menu']['breadcrumbs'][:-1]],
                                          [p['name'] for p in resource['en']['menu']['breadcrumbs'][:-1]]),
                'uri': resource['ru']['menu']['breadcrumbs'][-1]['uri'],
            }
        }

        doc.emit_body(body)

        doc.emit_sort_attr('popularity', data['ru']['menu']['popularity'])

        doc.emit_factor('popularity', normalize(data['ru']['menu']['popularity'], 400))

        doc.emit_factor('level', data['ru']['menu']['level'])
        doc.emit_factor('virtual', int(data['ru']['menu']['virtual']))
        doc.emit_factor('archive', int(data['ru']['menu']['archive']))
        doc.emit_factor('lastUpdated', date_as_factor(updated))

        for i, parent in enumerate(resource['ru']['menu']['breadcrumbs']):
            # берем самый старший родитель-проект
            if not parent['is_report'] and parent['id'].split(':')[0] == 'project':
                label_en = resource['en']['menu']['breadcrumbs'][i]['name']
                doc.emit_facet_attr('project', parent['uri'],
                                    label=parent['name'], label_en=label_en)
            break

        for region in resource['ru']['menu']['regions']:
            try:
                kwargs = {'alpha%s' % str(len(region)): region}
                country = pycountry.countries.get(**kwargs)
                # FIXME: использование несуществующего callable _
                #  Вероятно, это translate/gettext
                labels = {'label': _(country.name), 'label_en': country.name}  # noqa
            except KeyError:
                labels = {'label': region, 'label_en': region}

            doc.emit_facet_attr('region', region, **labels)

        def create_snippet(lang):
            description = get_short_desc(get_text_content(resource[lang]['meta']['desc_wiki_raw'] or ''),
                                         200)

            return {
                'title': resource[lang]['menu']['name'],
                'breadcrumbs': [
                    {
                        'url': urljoin(get_document_url('stat'), p.get('uri')),
                        'name': p['name']}
                    for p in resource[lang]['menu']['breadcrumbs']],
                'description': description,
                'virtual': data['ru']['menu']['virtual'],
                'level': data['ru']['menu']['level'],
                'archive': data['ru']['menu']['archive'],
            }

        doc.emit_snippet(create_snippet('ru'), 'ru')
        doc.emit_snippet(create_snippet('en'), 'en')

        self.next('store', document=doc, body_format='json')
