# coding=utf-8

import json

from django.conf import settings
from api.manager.tag_manager import get_bodypart_tags_with_tag_filter
from api.models import (
    Service,
    City,
    Province,
    Tag,
    TAG_TYPE,
    Doctor,
)
from api.tool.filter_tool import (
    COMMON_AREA_CACHE_KEY,
    COMMON_TAG_CACHE_KEY,
    SERVICE_AREA_CACHE_KEY,
    SERVICE_TAG_CACHE_KEY,
    DOCTOR_AREA_CACHE_KEY,
    SERVICE_AREA_CACHE_KEY_V1,
    SERVICE_AREA_CACHE_KEY_V2,
    DOCTOR_AREA_CACHE_KEY_V1,
    DOCTOR_AREA_CACHE_KEY_V2,
    DOCTOR_AREA_CACHE_KEY_V3,
    COMMON_AREA_CACHE_KEY_V1,
    COMMON_AREA_CACHE_KEY_V2,
    COMMON_AREA_CACHE_KEY_V3,
    FILTER_AREA_CACHE_KEY_V1,
)
from api.tool.filter_tool import build_special_area_filter
from api.tool.filter_tool import build_special_tag_filter
from api.tool.filter_tool import campaign_to_special
from api.tool.filter_tool import generate_area_filter_by_doctors, generate_doctor_area_filter, \
    generate_doctor_area_filter_v2
from api.tool.filter_tool import generate_area_filter_by_service, generate_service_area_filter, \
    generate_areas_list_v2, generate_areas_list
from api.tool.filter_tool import generate_tag_filter_by_service
from api.tool.filter_tool import get_all_areas, get_all_areas_v1, get_all_areas_v2
from api.tool.filter_tool import get_all_tags
from api.tool.log_tool import logging_exception
from api.tool.service_extra_filters import ExtraFilterWithName
from api.tool.service_tool import get_city_ids_has_online_service
from rpc.cache import (
    page_cache,
    make_cache_key,
    filter_cache,
    service_home_city_cache,
)
from gaia.routers import thread_local
from rpc.decorators import bind, cache_page


@bind('api/filter/service_home_city')
@cache_page(120)
def get_service_home_filter():
    key = 'service_home_city_key'
    try:
        city_data = service_home_city_cache.get(key)
        city_data = json.loads(city_data)
        city_ids = city_data['service_home_city_ids']
    except:
        logging_exception()
        city_ids = []

    cities = City.objects.filter(id__in=city_ids)
    cities_dict = {}
    for city_data in cities:
        if not city_data.id:
            continue
        cities_dict.setdefault(city_data.id[0], [])
        cities_dict[city_data.id[0]].append(
            {'id': city_data.id, 'name': city_data.name})

    result = []
    hot_cities = {
        'initial': u'热',
        'title': u'热门城市',
        'inline_block': True,
        'is_auto_located': False,
        'cities': settings.HOT_CITIES,
        'is_hot': True,
    }
    result.append(hot_cities)

    for city_initial in sorted(cities_dict.iterkeys()):
        data = {
            'initial': city_initial.upper(),
            'title': city_initial.upper(),
            'inline_block': False,
            'cities': cities_dict[city_initial],
            'is_auto_located': False,
        }
        result.append(data)
    return result


@bind('api/filter/provinces')
@cache_page(3600)
@thread_local(DB_FOR_READ_OVERRIDE=settings.SLAVE_DB_NAME)
def provinces_filter():
    """ v5.6.0 更新 地区筛选器按照取美购频道的顺序
    """
    province_ids = set(Service.objects.filter(is_online=True).values_list(
        'doctor__hospital__city__province', flat=True))

    provinces = Province.objects.filter(id__in=province_ids)
    result = [province.province_data() for province in provinces]

    return {'provinces': result}


@bind('api/filter/country')
def country_filter():
    """
    changelog:
    v5.9.1 创建 在之前地区筛选器(provinces_filter)基础上增加国家级别
    v6.0.0 修改 提到公共函数中调用 通用的地区筛选器 cache时间固定
    """
    areas = filter_cache.get(COMMON_AREA_CACHE_KEY)
    if areas:
        return json.loads(areas)

    areas = get_all_areas()
    return areas


@bind('api/filter/country/v1')
def country_filter_v1(exclude_gat=False):
    areas = filter_cache.get(COMMON_AREA_CACHE_KEY_V1)
    if areas:
        return json.loads(areas)

    areas = get_all_areas_v1(exclude_gat=exclude_gat)
    return areas


@bind('api/filter/country/v2')
def country_filter_v2(exclude_gat=True, lat='0', lng='0'):
    areas = filter_cache.get(COMMON_AREA_CACHE_KEY_V2)
    if areas:
        return json.loads(areas)

    return get_all_areas_v2(exclude_gat=exclude_gat)


@bind('api/filter/country/v3')
def country_filter_v2(exclude_gat=True):
    areas = filter_cache.get(COMMON_AREA_CACHE_KEY_V3)
    if areas:
        return json.loads(areas)

    areas = get_all_areas_v2(exclude_gat=exclude_gat)
    return areas


@bind('api/filter/countries')
def countries_filter(exclude_gat=True):
    """获取地区列表，过滤掉没有美购的地区。"""

    areas = filter_cache.get(FILTER_AREA_CACHE_KEY_V1)
    if areas:
        return json.loads(areas)

    cities = get_city_ids_has_online_service()
    areas = get_all_areas_v2(cities=cities, exclude_gat=exclude_gat)
    return areas


@bind('api/filter/service_areas')
def get_areas_by_services():
    """
    通过在线美购过滤掉没有美购的地区生成筛选器选项
    changelog:
    v6.0.0 创建
    """
    cache_area = filter_cache.get(SERVICE_AREA_CACHE_KEY)
    if cache_area:
        return json.loads(cache_area)

    cities = get_city_ids_has_online_service()
    areas = generate_areas_list(cities)
    return areas


@bind('api/filter/service_areas/v1')
def get_service_areas():
    areas = filter_cache.get(SERVICE_AREA_CACHE_KEY_V1)
    if areas:
        return json.loads(areas)

    services = Service.objects.filter(is_online=True)
    areas = generate_service_area_filter(services)
    return areas


@bind('api/filter/service_areas/v2')
def get_service_areas_v2(lat='0', lng='0'):
    areas = filter_cache.get(SERVICE_AREA_CACHE_KEY_V2)
    if areas:
        return json.loads(areas)

    cities = get_city_ids_has_online_service()
    return generate_areas_list_v2(cities)


@bind('api/filter/doctor_areas')
def get_areas_by_doctors():
    """
    通过在线医生过滤掉没有医生的地区生成筛选器选项
    changelog:
    v6.0.0 创建
    """
    cache_area = filter_cache.get(DOCTOR_AREA_CACHE_KEY)
    if cache_area:
        return json.loads(cache_area)

    doctors = Doctor.objects.filter(is_online=True)
    areas = generate_area_filter_by_doctors(doctors)
    return areas


@bind('api/filter/doctor_areas/v1')
def get_doctor_areas():
    areas = filter_cache.get(DOCTOR_AREA_CACHE_KEY_V1)
    if areas:
        return json.loads(areas)

    doctors = Doctor.objects.filter(is_online=True)
    areas = generate_doctor_area_filter(doctors)
    return areas


@bind('api/filter/doctor_areas/v2')
def get_doctor_areas_v2(lat='0', lng='0'):
    """获取有医生的城市列表。"""

    areas = filter_cache.get(DOCTOR_AREA_CACHE_KEY_V2)
    if areas:
        return json.loads(areas)

    doctors = Doctor.objects.filter(is_online=True)
    return generate_doctor_area_filter_v2(doctors)


@bind('api/filter/doctor_areas/v3')
def get_doctor_areas_v3():
    """获取有医生的城市列表。"""

    areas = filter_cache.get(DOCTOR_AREA_CACHE_KEY_V3)
    if areas:
        return json.loads(areas)

    doctors = Doctor.objects.filter(is_online=True)
    areas = generate_doctor_area_filter_v2(doctors)
    return areas


@bind('api/filter/service_tags')
def get_tags_by_services(ordering=False):
    """
    通过在线美购过滤掉没有美购的二级tag生成筛选器选项
    changelog:
    v6.0.0 创建
    """
    # cache_tag = filter_cache.get(SERVICE_TAG_CACHE_KEY)
    # if cache_tag:
    #     return {'tags': json.loads(cache_tag)}

    services = Service.objects.filter(is_online=True)
    tags = generate_tag_filter_by_service(services, ordering=ordering)
    return {'tags': tags}


@bind('api/filter/special_activity_tags')
def special_activity_tags(special_id=None, is_campaign=False):
    if is_campaign:
        special_id = campaign_to_special(special_id)
    cache_key = make_cache_key(build_special_tag_filter, special_id=special_id)
    tags = page_cache.get(cache_key)
    if tags:
        return json.loads(tags)
    else:
        return build_special_tag_filter(special_id=special_id)


@bind('api/filter/special_activity_areas')
def special_activity_areas(special_id=None, is_campaign=False):
    if is_campaign:
        special_id = campaign_to_special(special_id)
    cache_key = make_cache_key(build_special_area_filter, special_id=special_id) + '-v1'
    areas = page_cache.get(cache_key)
    if areas:
        return json.loads(areas)
    else:
        return build_special_area_filter(special_id=special_id, exclude_gat=True)


@bind('api/filter/tags')
def get_tags(with_hot=True, with_level_3=False):
    """
    changelog:
    v6.0.0 修改 提到公共函数中调用
    """
    cache_key = COMMON_TAG_CACHE_KEY.format(with_hot, with_level_3)
    tags = filter_cache.get(cache_key)
    if tags:
        return json.loads(tags)

    return get_all_tags(with_hot=with_hot, with_level_3=with_level_3)


@bind('api/filter/tags_for_doctor_organization')
def get_tags_for_doctor_organization(tag_ids=None):
    '''
    :param doctor_id_for_diary: 
    :param organization_id_for_diary: 
    :return: 
    '''
    permitted_tag_id_list = frozenset(
        Tag.objects.filter(
            id__in=tag_ids
        ).values_list('id', flat=True)
    )
    tags = get_bodypart_tags_with_tag_filter(
        permitted_tag_id_list=permitted_tag_id_list)

    return {'tags': tags}


@bind('api/filter/sections')
def get_sections():
    sections_list = Tag.objects.filter(is_online=True,
                                       tag_type=TAG_TYPE.BODY_PART)
    sections_list = sections_list.order_by('ordering')
    sections = [section.get_tag_info() for section in sections_list]
    return {'sections': sections}


@bind('api/filter/extra')
def extra_filter(version='0.0.0'):
    result = [
        {
            'key': efn.key,
            'name': efn.name,
        }
        for efn in ExtraFilterWithName.get_all(version)
    ]

    return {'extra_filter': result}