#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
import json

from django.db.models import Q

from api.models.college import College
from rpc.cache import recommend_college_cache
from rpc.decorators import bind, cache_page
from rpc.tool.error_code import gen, CODES


def sort_college_ids(count, ordinary_ids=None, recommend_ids=None):
    """
    根据关注数，排序处理大学id
    :param count: 需要获取的数量
    :param ordinary_ids: 非推荐的大学id, 需要排序 list
    :param recommend_ids: 推荐的大学id, 需要去重 list
    :return: [] list id 列表
    """
    recommend_dic = recommend_college_cache.hgetall("recommend_colleges")
    l = [(json.loads(k), json.loads(v)) for k, v in recommend_dic.items()]

    college_id_list = []
    _count = count
    for info in sorted(l, key=lambda x: x[0], reverse=True):
        if _count <= 0:
            break

        _, _ids = info
        if recommend_ids:
            _ids = set(_ids) - set(recommend_ids)  # 如果有推荐数据，则去重
        if ordinary_ids:
            _ids = set(_ids) & set(ordinary_ids)  # 如果存在需要排序的大学id，则取交集

        _size = min(_count, len(_ids))  # 筛选出的数据长度
        college_id_list.extend(random.sample(_ids, _size))  # 数据打散(产品要求打撒) + 数据拼接
        _count -= _size

    return college_id_list[:count]  # 防止数据过长


@bind("api/college/search_by_keywords")
def get_college_by_keywords(keywords):
    """
    通过关键词搜索对应的大学
    :param keywords:关键词
    :return:
    """
    if not keywords:
        return []

    colleges = College.objects.filter(name__istartswith=keywords, is_online=True).values("id", "name")
    return list(map(dict, colleges))


@bind("api/college/recommend")
def get_recommend_college(current_city_id=None, count=10):
    """
    通过当前城市, 推荐大学
    :param current_city_id: 当前城市
    :param count: 推荐数据
    :return:
    """
    hot_colleges = []
    query = Q(is_online=True)

    if current_city_id:
        query &= Q(city_id=current_city_id)
    r_query = query & Q(is_recommend=True)  # 推荐的数据

    colleges = College.objects.filter(query)  # 全部大学
    have_colleges = colleges.exists()  # 是否有大学

    if not have_colleges:  # 没有大学，则推荐全国大学
        r_query = Q(is_online=True, is_recommend=True)
    recommends = College.objects.filter(r_query).order_by("-id").values("id", "name")  # 推荐的大学

    recommend_ids = [college["id"] for college in recommends]  # 推荐的大学id列表
    hot_colleges.extend(list(map(dict, recommends)))  # 先拼接 推荐的数据

    # 数据补齐, 返回满足要求的大学id
    _count = count - len(hot_colleges)
    if _count <= 0:
        return hot_colleges[:count]

    sorted_colleges_ids = []
    if current_city_id and colleges.exists():
        current_city_college_ids = list(colleges.values_list("id", flat=True))
        sorted_colleges_ids = sort_college_ids(
            count=_count,
            recommend_ids=recommend_ids,
            ordinary_ids=current_city_college_ids
        )

    elif not current_city_id or (current_city_id and not have_colleges):
        sorted_colleges_ids = sort_college_ids(
            count=_count,
            recommend_ids=recommend_ids
        )

    if not sorted_colleges_ids:
        return hot_colleges

    query = Q(pk__in=sorted_colleges_ids, is_online=True)
    current_city_college = College.objects.filter(query).values("id", "name")

    # 处理补齐数据
    _data = [None] * _count
    for info in current_city_college:
        _index = sorted_colleges_ids.index(info["id"])
        _data[_index] = info
    hot_colleges += list(filter(None, _data))  # 过滤掉为None的数据

    return hot_colleges