from django.conf import settings as django_settings
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from askbot.forms import (
    AnalyticsActivityForm,
    AnalyticsActivityField,
    AnalyticsContentField
)
from django.contrib.contenttypes.models import ContentType
from askbot.models import User, Group, Post
from askbot.models.analytics import DailyGroupSummary, Event
from askbot.utils.functions import get_paginated_list
from askbot.utils.analytics_utils import (
    get_analytics_default_segment_config,
    get_named_segment_config_by_group_id,
    get_segment_name
)
from askbot.views.analytics.utils import (
    get_date_selector_url_func,
    filter_events_by_users_segment,
    filter_events_by_content_segment
)


def get_activity_segment_breadcrumb(activity_segment, dates):
    """get breadcrumb for activity segment"""
    return {
        'url': reverse('analytics_activity', kwargs={'activity_segment': activity_segment, 'content_segment': 'all-content', 'users_segment': 'all-users', 'dates': dates}),
        'name': AnalyticsActivityField.get_field_display(activity_segment),
        'is_global_segment': activity_segment == 'all-activity'
    }


def get_content_segment_breadcrumb(activity_segment, content_segment, dates):
    """get breadcrumb for content segment"""
    return {
        'url': reverse('analytics_activity', kwargs={'activity_segment': activity_segment, 'content_segment': content_segment, 'users_segment': 'all-users', 'dates': dates}),
        'name': AnalyticsContentField.get_field_display(content_segment),
        'is_global_segment': content_segment == 'all-content'
    }


def get_users_segment_name(users_segment):
    """get name for users segment"""
    if users_segment == 'all-users':
        return _('All Users')
    return get_segment_name(users_segment)


def get_named_segment_breadcrumb(named_segment_config, dates):
    """get breadcrumb for named segment"""
    return {
        'url': reverse('analytics_activity',
                    kwargs={'activity_segment': 'all-activity',
                            'content_segment': 'all-content',
                            'users_segment': named_segment_config['slug'],
                            'dates': dates}),
        'name': named_segment_config['name'],
        'is_global_segment': False
    }


def get_user_breadcrumb(user, dates):
    """get breadcrumb for user"""
    return {
        'url': reverse('analytics_activity',
                        kwargs={'activity_segment': 'all-activity',
                                'content_segment': 'all-content',
                                'users_segment': 'user:' + str(user.id),
                                'dates': dates}),
        'name': user.username,
        'is_global_segment': False
    }

def get_group_breadcrumb(group, dates):
    """get breadcrumb for group"""
    return {
        'url': reverse('analytics_activity',
                        kwargs={'activity_segment': 'all-activity',
                                'content_segment': 'all-content',
                                'users_segment': 'group:' + str(group.id),
                                'dates': dates}),
        'name': group.name,
        'is_global_segment': False
    }


def get_default_segment_breadcrumb(dates):   
    """get breadcrumb for default segment"""
    default_segment_config = get_analytics_default_segment_config()
    return {
        'url': reverse('analytics_activity',
                        kwargs={'activity_segment': 'all-activity',
                                'content_segment': 'all-content',
                                'users_segment': default_segment_config['slug'],
                                'dates': dates}),
        'name': default_segment_config['name'],
        'is_global_segment': False 
    }


def get_users_segment_breadcrumbs(activity_segment, content_segment, users_segment, dates):
    """get breadcrumbs for users segment"""
    url = reverse('analytics_activity',
                  kwargs={'activity_segment': activity_segment,
                          'content_segment': content_segment,
                          'users_segment': users_segment,
                          'dates': dates})

    users_segment_name = None
    if users_segment == 'all-users':
        users_segment_name = _('All Users')
    else:
        users_segment_name = get_segment_name(users_segment)

    if users_segment_name:
        return [{
            'url': url,
            'name': users_segment_name,
            'is_global_segment': users_segment == 'all-users'
        }]

    if users_segment.startswith('user:'):
        # get first analytics group to which this user belongs
        user = User.objects.get(id=users_segment.split(':')[1])
        group = user.get_groups(used_for_analytics=True).first()

        if not group:
            return [{'url': url,
                     'name': user.username,
                     'is_global_segment': False}]

        named_segment_config = get_named_segment_config_by_group_id(group.id)
        if named_segment_config:
            return [
                get_named_segment_breadcrumb(named_segment_config, dates),
                get_user_breadcrumb(user, dates)
            ]

        has_named_segments = bool(django_settings.ASKBOT_ANALYTICS_NAMED_SEGMENTS)
        if has_named_segments:
            return [
                get_default_segment_breadcrumb(dates),
                get_group_breadcrumb(group, dates),
                get_user_breadcrumb(user, dates)
            ]
        analytics_group_count = Group.objects.filter(used_for_analytics=True).count()
        if analytics_group_count > 1:
            return [
                get_group_breadcrumb(group, dates),
                get_user_breadcrumb(user, dates)
            ]
        return [get_user_breadcrumb(user, dates)]

    if users_segment.startswith('group:'):
        group = Group.objects.get(id=users_segment.split(':')[1])
        named_segment_config = get_named_segment_config_by_group_id(group.id)
        if named_segment_config:
            return [get_named_segment_breadcrumb(named_segment_config, dates)]

        has_named_segments = bool(django_settings.ASKBOT_ANALYTICS_NAMED_SEGMENTS)
        if has_named_segments:
            return [
                get_default_segment_breadcrumb(dates),
                get_group_breadcrumb(group, dates)
            ]
        analytics_group_count = Group.objects.filter(used_for_analytics=True).count()
        if analytics_group_count > 1:
            return [get_group_breadcrumb(group, dates)]
        return []
                
    return []


def collapse_redundant_breadcrumbs(breadcrumbs):
    """
    Going in reverse order, towards the first breadcrumb,
    remove all items which have "is_global_segment" set to True.
    Keep only one item for each group of items with "is_global_segment" set to True.

    Then remove all items which have redurndant urls.
    """
    # find the index of the last breadcrumb to keep
    count = len(breadcrumbs)
    idx_to_keep = count - 1
    for idx in range(count - 1, -1, -1):
        if breadcrumbs[idx]['is_global_segment'] == False:
            break
        idx_to_keep = idx
        if idx == 1:
            break

    breadcrumbs = breadcrumbs[:idx_to_keep + 1]

    # now remove all items which have redurndant urls
    urls_visited = set()
    filtered_breadcrumbs = []
    for breadcrumb in breadcrumbs:
        if breadcrumb['url'] in urls_visited:
            continue
        filtered_breadcrumbs.append(breadcrumb)
        urls_visited.add(breadcrumb['url'])
    return filtered_breadcrumbs


def get_breadcrumbs(activity_segment, content_segment, users_segment, dates):
    """get breadcrumbs for analytics activity page
    """
    breadcrumbs = [
        {
            'url': reverse('analytics_index'),
            'name': _('Analytics'),
            'is_global_segment': True
        },
        {
            'url': reverse('analytics_activity', kwargs={'activity_segment': 'all-activity',
                                                         'content_segment': 'all-content',
                                                         'users_segment': 'all-users',
                                                         'dates': dates}),
            'name': AnalyticsActivityField.get_field_display('all-activity'),
            'is_global_segment': True
        },
        get_activity_segment_breadcrumb(activity_segment, dates),
        get_content_segment_breadcrumb(activity_segment, content_segment, dates),
    ]
    breadcrumbs.extend(get_users_segment_breadcrumbs(activity_segment, content_segment, users_segment, dates))
    breadcrumbs = collapse_redundant_breadcrumbs(breadcrumbs)
    return breadcrumbs


def analytics_activity(request, activity_segment=None, content_segment=None, users_segment=None, dates=None):
    """analytics activity page"""
    if not request.user.is_authenticated or not request.user.is_admin_or_mod():
        return HttpResponseForbidden()

    earliest_summary = DailyGroupSummary.objects.order_by('date').first() # pylint: disable=no-member
    if earliest_summary is None:
        earliest_possible_date = timezone.now().date()
    else:
        earliest_possible_date = earliest_summary.date
    form = AnalyticsActivityForm({
        'activity_segment': activity_segment,
        'content_segment': content_segment,
        'users_segment': users_segment,
        'dates': dates
    }, earliest_possible_date=earliest_possible_date)

    if not form.is_valid():
        default_params = {
            'activity_segment': 'all-activity',
            'content_segment': 'all-content',
            'users_segment': 'all-users',
            'dates': 'all-time'
        }
        return HttpResponseRedirect(reverse('analytics_activity', kwargs=default_params))

    event_types = form.cleaned_data['activity_segment']
    users_url_segment = form.cleaned_data['users_segment']
    start_date, end_date = form.cleaned_data['dates']

    if end_date == timezone.now().date():
        end_date = timezone.now()

    events = Event.objects.filter(timestamp__gte=start_date, timestamp__lte=end_date)
    events = events.order_by('-timestamp')
    events = filter_events_by_content_segment(events, content_segment)
    events = filter_events_by_users_segment(events, users_segment)
    events = events.filter(event_type__in=event_types)
    events, paginator_context = get_paginated_list(request, events, 20)

    data = {
        'Event': Event,
        'events': events,
        'post_content_type': ContentType.objects.get_for_model(Post),
        'event_types': event_types,
        'users_url_segment': users_url_segment,
        'dates': dates,
        'start_date': start_date,
        'end_date': end_date,
        'paginator_context': paginator_context,
        'breadcrumbs': get_breadcrumbs(activity_segment,
                                       content_segment,
                                       users_url_segment,
                                       dates),
        'date_selector_url_func': get_date_selector_url_func('analytics_activity',
                                                             content_segment=content_segment,
                                                             activity_segment=activity_segment,
                                                             users_segment=users_url_segment)
    }

    return render(request, 'analytics/analytics_activity.html', data)