import logging
from datetime import datetime

from django.conf import settings

from intranet.search.core.snippets.at import ClubSnippet
from intranet.search.core.sources.utils import (
    get_text_content,
    date_as_factor,
    normalize,
)
from intranet.search.core.utils.cache import Urls
from intranet.search.core.swarm.indexer import Indexer
from . import utils


log = logging.getLogger(__name__)


class Source(Indexer):

    def __init__(self, options):
        super().__init__(options)
        self.urls = Urls(self.cache_storage, name='club_urls')

    def do_walk(self, **kwargs):
        params = {'_fields': 'uid,login'}
        if self.options['keys']:
            params['login'] = ','.join(self.options['keys'])

        users = utils.get_staff_users(params)
        limit = self.options.get('limit')
        for i, user in enumerate(users, 1):
            if not self.options['keys'] and limit and i > limit:
                break

            self.next('fetch', user=user)

    def do_fetch(self, user, **kwargs):
        for club in utils.user_clubs(user['uid']):
            club_id = utils.get_id(club['id'])
            if int(club_id) == int(user['uid']):
                continue

            url = utils.repair_link(club['links']['www'] or '')
            if not url:
                log.warning('Empty club url: %s', club_id)
                continue

            if not self.urls.visit_url(url):
                continue

            posts = get_posts_info(club_id)
            description = get_club_description(club_id)

            self.next('create', club=club, posts=posts, description=description)

    def do_create(self, club, posts, description, **kwargs):
        data = {
            'id': utils.get_id(club['id']),
            'url': utils.repair_link(club['links']['www'] or ''),
            'name': club['name'] or '',
            'members_count': club['members_count'] or 0,
            'userpic': club['links']['avatar_url'],
            'community_type': club['community_type'] or '',
        }
        data.update(posts)
        data['description'] = description[:300]

        doc = self.create_document(data['url'], data['last_post_date'])
        doc.emit_factor('clubsMembersCount', normalize(data['members_count'], 10000))
        doc.emit_factor('clubsThreadsCount', normalize(data['threads_count'], 10000))
        doc.emit_factor('clubsFirstPost', date_as_factor(data['first_post_date']))
        doc.emit_factor('clubsLastPost', date_as_factor(data['last_post_date']))

        body = {
            '!hidden': {
                'clubs_name': data['name'],
                'clubs_url': data['url'],
            },
            'clubs_description': description,
        }

        doc.emit_body(body)

        if data['last_post_date'] == data['first_post_date'] == datetime.fromtimestamp(0):
            data['last_post_date'] = data['first_post_date'] = None

        doc.emit_snippet(ClubSnippet(data), 'ru')

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


def get_club_description(club_id):
    """
    Отдаёт описание клуба. Описанием считаем первый пост в ручке постов клуба
    """
    url = settings.ISEARCH['api']['at']['club_posts'].url().format(feed_id=club_id)
    posts = utils.get_posts(url)
    latest_post = next(posts, {})
    return get_text_content(latest_post.get('content', ''))


def get_posts_info(club_id):
    url = settings.ISEARCH['api']['at']['club_posts'].url().format(feed_id=club_id)

    threads_count = 0
    first_post_date = datetime.max
    last_post_date = datetime.min

    for post in utils.get_posts(url):
        threads_count += 1

        update = utils.parse_date(post['updated']).replace(tzinfo=None)
        first_post_date = update

        if last_post_date < update:
            last_post_date = update

    if not threads_count:
        return {
            'threads_count': 0,
            'first_post_date': datetime.fromtimestamp(0),
            'last_post_date': datetime.fromtimestamp(0),
        }
    else:
        return {
            'threads_count': threads_count,
            'first_post_date': first_post_date,
            'last_post_date': last_post_date,
        }
