# coding: utf-8

from __future__ import unicode_literals

import arrow
from django.conf import settings

from cab.core import widgets
from cab.sources import review
from cab.sources import startrek_goals
from cab.sources import staff_api
from cab.sources import feedback
from cab.utils import multifetch
from cab.utils import datetimes
from cab.utils import validators


class ReviewDefault(widgets.BaseEndpointHandler):

    def handle(self, data):

        sources = {
            'reviews': (self.auth,),
            'feedback': (self.auth,),
            'goals': (self.auth,),
        }

        results = multifetch.collect_data(
            env_prefix='review',
            func=fetch,
            args_dict=sources,
        )

        if results['reviews'].is_error or not results['reviews'].value:
            return {}

        return {
            source_id: result.value
            for source_id, result in results.items()
        }


class Vteam(widgets.BaseEndpointHandler):

    class Validator(validators.WidgetValidator):
        login = validators.LoginField(required=False)

    def handle(self, data):
        return []


@multifetch.fetcher
def fetch(args):
    source_id, func_args = args[0], args[1:]
    return globals()['get_' + source_id + '_data'](*func_args)


def get_feedback_data(auth):
    fb_data = feedback.get_user_info(auth)
    if not fb_data:
        return
    request_feedback_url = feedback.RESOURCES['request_feedback_web'].format(
        staff_id=auth.staff_id)
    return fb_data and {
        'incoming_requests_count': fb_data.get('active_incoming_request_count', 0),
        'outcoming_requests_count': fb_data.get('active_request_count', 0),
        'request_feedback_url': request_feedback_url,
        'send_feedback_url': feedback.WEB_URL,
    }


def get_goals_data(auth):
    today = datetimes.today()

    login = staff_api.get_person_data(staff_id=auth.staff_id)['login']
    goals_data = [
        goal for goal in startrek_goals.get_in_work_goals(auth, login)
        if goal['statusStartTime'] is None or
        datetimes.days_between(goal['statusStartTime'], today) <= startrek_goals.GOALS_ACTUAL_DAYS
    ]

    collected = {
        status_slug: [] for status_slug in startrek_goals.GS.values()
        if status_slug not in 'new'
    }
    collected.update(no_deadline=[], expired=[])

    for goal in goals_data:
        formatted_goal = startrek_goals.format_goal_for_response(goal)
        status = goal['status']['key']
        status_slug = startrek_goals.GS[status]
        deadline = goal['deadline']
        collected[status_slug].append(formatted_goal)

        if status in startrek_goals.GS_INACTIVE:
            continue

        if deadline is None:
            collected['no_deadline'].append(formatted_goal)
        elif _is_deadline_passed(goal):
            collected['expired'].append(formatted_goal)

    results = {}
    for marker, goals_list in collected.items():
        results[marker + '_count'] = len(goals_list)
        results[marker + '_url'] = _build_goals_url(auth, marker)
        if settings.DEBUG_DATA:
            results[marker] = goals_list
    return results


# https://st.yandex-team.ru/STAFF-7459
REASONABLE_REVIEW_VISIBILITY_IN_DAYS = 42


def get_reviews_data(auth):
    review_list = review.get_review_list(
        auth=auth,
        statuses=['in_progress'],
        fields=[
            'start_date',
            'finish_feedback_date',
            'finish_submission_date',
            'finish_calibration_date',
            'finish_approval_date',
            'finish_date',
        ]
    )['reviews']
    results = []

    for review_item in review_list:
        start_date = review_item['start_date']

        review_being_visible = datetimes.days_between(start_date, datetimes.today())
        if review_being_visible > REASONABLE_REVIEW_VISIBILITY_IN_DAYS:
            continue

        review_id = review_item['id']
        review_name = review_item['name']
        stats = review.get_review_stats(auth=auth, id=review_id)
        results.append(
            {
                'id': review_id,
                # раньше ревью было привязано к подразделению — формат
                # нужно поправить
                'department': {
                    'url': None,
                    'name': review_name
                },
                'stages': _get_stages(review_item),
                'stats': stats['all'] and {
                    'waiting_for_evaluation': stats['waiting_for_evaluation_total'],
                    'waiting_for_approve': stats['waiting_for_approve_total'],
                    'waiting_for_discuss': stats['discuss'],
                    'waiting_for_announce': stats['waiting_for_announce_total'],
                },
            }
        )

    return results


def _get_stages(info):
    return [
        {
            'id': 'feedback',
            'start': info['start_date'],
            'end': info['finish_feedback_date'],
        },
        {
            'id': 'submission',
            'start': info['finish_feedback_date'],
            'end': info['finish_submission_date'],
        },
        {
            'id': 'calibration',
            'start': info['finish_submission_date'],
            'end': info['finish_calibration_date'],
        },
        {
            'id': 'approval',
            'start': info['finish_calibration_date'],
            'end': info['finish_approval_date'],
        },
        {
            'id': 'announce',
            'start': info['finish_approval_date'],
            'end': info['finish_date'],
        },
    ]


def _build_goals_url(auth, marker):
    params = {
        'Goal Importance': ','.join([
            startrek_goals.GI_REGULAR,
            startrek_goals.GI_DEPARTMENT,
            startrek_goals.GI_COMPANY
        ]),
    }

    if marker == 'no_deadline':
        params['status'] = ','.join(startrek_goals.GS_ACTIVE)
        params['Deadline'] = 'empty()'
    else:
        params['status'] = getattr(startrek_goals, 'GS_' + marker.upper(), None)

    return startrek_goals.build_filter_url(auth, **params)


def _is_deadline_passed(goal):
    today = datetimes.today()

    if goal['deadline'] is None:
        return False
    # костыль: голс присылает для квартала его начала, хотя дедалйном должен
    # быть конец
    deadline_quarter_first_day = goal['deadline']
    deadline = arrow.get(deadline_quarter_first_day).replace(months=+3).replace(days=-1)
    return deadline.date() < today
