# coding: utf-8
import arrow

from cab.sources import gap, review, staff, staff_api, startrek_goals

from . import const


def get_ids(persons):
    return [p['id'] for p in persons]


def get_logins(persons):
    return [p['login'] for p in persons]


def fetch_staff_whistlah(auth, persons, fields):
    return staff.get_last_activity(
        auth=auth,
        logins=get_logins(persons),
    )


def fetch_staff_api_person(auth, persons, fields):
    all_fields = set(fields) & set(const.STAFF_API_FIELDS_MAPPING)
    api_fields = []
    for field in all_fields:
        api_field = const.STAFF_API_FIELDS_MAPPING[field]
        if isinstance(api_field, dict):
            api_fields.extend(api_field.values())
        elif isinstance(api_field, (list, tuple)):
            api_fields.extend(api_field)
        else:
            api_fields.append(api_field)
    return staff_api.get_persons_data(
        auth=auth,
        logins=get_logins(persons),
        fields=api_fields,
    )


def fetch_finance(auth, persons, fields):
    oebs_source = {
        'bonus_forecast': {'bonus_history', 'salary_history'},
        'last_bonus_payment': {'bonus_history'},
        'loans': {'current_loans'},
        'fte': {'current_salary'},
        'grade': {'grade_history'},
        'salary': {'salary_history'},
        'salary_forecast': {'salary_history'},
        'options': {'salary_history', 'options_history'},
        'options_vested': {'salary_history', 'options_history'},
        'options_vesting_forecast': {'salary_history', 'options_history'},
        'options_vesting_forecast_total': {'salary_history', 'options_history'},
        'options_vesting_forecast_count': {'options_history'},
        'options_vesting_forecast_cost': {'salary_history', 'options_history'},
        'last_salary_raise': {'salary_history'},
        'social_package': {'social_package'},
        'income_forecast': {'salary_history', 'bonus_history', 'options_history'},
        'year_bonus_payment': {'bonus_history'},
        'options_monetary_forecast': {'options_history'},
        'salary_last_year': {'salary_history'},
        'bonus_last_year': {'bonus_history'},
        'income_last_year': {'salary_history', 'bonus_history', 'options_history'},
        'incomes': {'salary_history', 'bonus_history', 'options_history'},
        'options_monetary_last_year': {'options_history'},
    }
    oebs_fields = set()
    for field in fields:
      oebs_fields |= oebs_source.get(field, {field})
    oebs_fields = list(oebs_fields)
    return review.get_oebs_data(
        auth=auth,
        fields=oebs_fields,
        logins=get_logins(persons)
    )


def fetch_staff_personal(auth, persons, fields):
    return staff.get_personal_fields(auth=auth, logins=get_logins(persons))


def fetch_gap_vacations(auth, persons, fields):
    now = arrow.now()
    year_ago = now.replace(years=-1).date()
    year_after = now.replace(years=1).date()

    get_gaps_kwargs = {
        'auth': auth,
        'logins': get_logins(persons),
        'workflows': ['vacation'],
    }

    if 'vacation_days_used' in fields:
        get_gaps_kwargs['date_from'] = year_ago
    if 'vacation_days_planned' in fields:
        get_gaps_kwargs['date_to'] = year_after

    return gap.get_gaps(**get_gaps_kwargs)


def fetch_goals(auth, persons, fields):
    logins = [p['login'] for p in persons]
    return {login: startrek_goals.get_important_goals(auth, login) for login in logins}


def fetch_review(auth, persons, fields):
    return review.get_person_reviews_announced(
        auth=auth,
        logins=get_logins(persons),
    )


def fetch_review_income_list(auth, persons, fields):
    return review.get_person_bi_income_list(
        auth=auth,
        logins=get_logins(persons),
    )


def fetch_review_assignments_list(auth, persons, fields):
    return review.get_person_bi_assignments_list(
        auth=auth,
        logins=get_logins(persons),
    )


def fetch_gap(auth, persons, fields):
    return gap.get_gaps(
        auth=auth,
        logins=get_logins(persons),
        only_one=True,
    )


def fetch_subordinate_departments(auth, persons, fields):
    # может и можно сделать запрос на нескольких, но это будет нетривиально и
    # вряд ли понадобится
    assert len(persons) == 1, 'not bulk fetcher'
    login = persons[0]['login']
    return {
        login: staff_api.get_subordinate_departments(auth, login=login)
    }


def fetch_subordinate_persons(auth, persons, fields):
    assert len(persons) == 1, 'not bulk fetcher'
    id_ = persons[0]['id']
    login = persons[0]['login']
    return {
        login: {
            # типа костыль, потому что в процессоре неоткуда взять
            # того для кого запрашиваем — если проблема будет повторяться —
            # переделать
            'login': login,
            'subordinates': staff_api.get_subordinate_persons(
                auth=auth,
                id_=id_,
                fields=[
                    'login',
                    'chief',
                ]
            ),
        }
    }
