# coding=utf-8
from talos.models.topic import Problem, TopicRankingScore
from data_sync.utils import tzlc
from gm_types.gaia import TOPIC_TYPE
from django.conf import settings
from utils.rpc import get_rpc_invoker
from django.db import connections, connection


def get_problems(pks):
    """
    :param pks:
    :return:
    """
    # r = get_rpc_invoker()
    problems = Problem.objects.filter(pk__in=pks)

    data = []
    params = []

    for p in problems:
        tids = [pt.tag_id for pt in p.problemtag_set.all()]
        params.append({
            "pid": p.id, "uid": p.user_id, "tids": tids,
            "sid": p.diary and p.diary.service_id,
            "did": p.diary and p.diary.doctor_id,
        })
        data.append(get_problem(p))

    # extras = r['api/dbmw/get_problem_extra'](params=params).unwrap()
    extras = get_problem_extra_batch(params=params)
    # assert len(extras) == len(data)

    for topic in data:
        topic['user'].update(extras.get(topic["id"], {}).get("user", {}))
        topic.update(extras[topic["id"]])
    # for idx, topic in enumerate(data):
    #     topic['user'].update(extras[idx].pop('user', {}))
    #     topic.update(extras[idx])
    return data


def get_problem_extra_batch(params):
    data = {}
    for param in params:
        data[param['pid']] = get_problem_extra(
            param['pid'], param['uid'], param['tids'],
            param['sid'], param['did'])
    return data

def get_problem_extra(pid, uid, tids, sid, did):
    """
    Get extra topic data.
    :param did: 帖子关联的医生
    :param sid: 帖子关联的美购
    :param tids: 帖子关联的TAG
    :param pid: topic id.
    :param uid: 帖子关联的用户.
    :return:
    """
    res = {}
    cur = connections[settings.ZHENGXING_DB].cursor()
    if sid:
        service_sql = "select is_online from api_service where id = {}".format(
            sid)
        cur.execute(service_sql)
        if not cur.fetchone():
            res['is_sink'] = True

    if did:
        doctor_sql = "select is_online from api_doctor where id = '{}'".format(did)
        cur.execute(doctor_sql)
        if not cur.fetchone():
            res['is_sink'] = True

    if uid:
        user_sql = """ select id, last_name from auth_user where id = {}""".format(uid)
        userextra_sql = """ select user_id, city_id from api_userextra where user_id = {}""".format(uid)
        doctor_user_sql = """ select id from api_doctor where user_id = {}""".format(uid)
        cur.execute(user_sql)
        user = cur.fetchone()
        cur.execute(userextra_sql)
        userextra = cur.fetchone()
        is_doctor = False
        cur.execute(doctor_user_sql)
        if cur.fetchall():
            is_doctor = True
        user_info = {
            "is_doctor": is_doctor,
        }
        city = userextra[1]
        if user:
            user_info["id"] = user[0]
            user_info["last_name"] = user[1]
            if city:
                user_info.update(get_area_tag_info(city, cur))
    else:
        user_info = {}
    res['user'] = user_info
    res['tags'] = []
    res['tag_ids'] = []
    res['closure_tag_ids'] = []
    if tids:
        tag_sql = """
            select id, name from api_tag
            where id in ({}) and
            is_online=true""".format(
                ','.join([str(tid) for tid in tids]))
        cur.execute(tag_sql)
        tags = cur.fetchall()
        res['tags'] = list(set([pt[1] for pt in tags]))
        tag_ids = list(set([pt[0] for pt in tags]))
        res['tag_ids'] = tag_ids
        closure_tag_ids = tag_ids
        # TODO
        if tag_ids:
            # 递归查询
            closure_tag_ids = get_v3_parent_tag_list(cur, tag_ids, tag_ids)
        res['closure_tag_ids'] = closure_tag_ids
    res['in_whitelist'] = False
    res['in_multitopic'] = False
    return res


def get_v3_parent_tag_list(cur, tag_list, stack):
    """
    获取tag_v_3标签的父级标签（递归查询）
    """
    if not stack:
        return tag_list
    parent_v3_tag_id_sql = """
        SELECT api_tag_v3_relation.parent_id as parent_id
        FROM api_tag_v3_relation 
            INNER JOIN api_tag_3_0 ON api_tag_v3_relation.parent_id = api_tag_3_0.id
        WHERE api_tag_v3_relation.is_online = True AND api_tag_3_0.is_online = True
        and api_tag_v3_relation.child_id in ({})""".format(
            ','.join([str(tid) for tid in tag_list]))
    cur.execute(parent_v3_tag_id_sql)
    parent_ids = cur.fetchall()
    v3_parent_tag_ids = [item[0] for item in parent_ids if item[0] not in tag_list]
    tag_list = tag_list + v3_parent_tag_ids
    return get_v3_parent_tag_list(cur, tag_list, v3_parent_tag_ids)
        

def get_area_tag_info(city_id, cur):
    """
    获取用户关联的城市、省份、国家标签id
    """
    if not city_id:
        return {}
    city_sql = """
        select api_city.tag_id as city_tag_id, api_province.tag_id as city_province_tag_id, api_country.tag_id as city_province_country_tag_id
            from api_city
            left join api_province on api_city.province_id = api_province.id
            left join api_country on api_province.country_id = api_country.id
        where api_city.id = '{}'
        """.format(city_id)
    cur.execute(city_sql)
    area_tag = cur.fetchone()
    if not area_tag:
        return {}
    return {
        'city_tag_id': area_tag[0],
        'city_province_tag_id': area_tag[1],
        'city_province_country_tag_id': area_tag[2],
    }


def get_problem(instance):
    p = instance
    res = {
        'id': p.id,
        'diary_id': p.diary_id,
        'doctor_num': p.doctor_num,
        'created_time': tzlc(p.created_time),
        'content': p.answer,
        'is_public': p.is_public,
        'is_online': p.is_online,
        'is_elite': p.selected_qa,
        'is_sink': p.is_sink,
        'is_topic': p.is_topic,
        'pgc_category': p.pgc_classfy.id if p.pgc_classfy else None,
        'flag': p.flag,
        'topic_type': p.topic_type,
        'private_status': p.private_status,
        'title': p.ask,
        'title2': p.title,
        'channel_headline': p.channel_headline,
        'user': {
            'id': p.user_id,
            'last_name': p.user.nickname,
        },
        'content_level': -1 #所属日记本星级
    }

    try:
        p.video
        res['has_video'] = True
    except Problem.video.RelatedObjectDoesNotExist:
        res['has_video'] = False

    if p.topic_type in (TOPIC_TYPE.ASK, TOPIC_TYPE.TOPIC):
        res['ranking_popularity'] = TopicRankingScore.get_pop_score(topic=p)
    else:
        res['ranking_popularity'] = 0.0

    if p.doctor_num > 0:
        res['has_doctor_reply'] = True  # 是否有医生回复
    else:
        res['has_doctor_reply'] = False

    if p.images.count() > 0:
        res['has_image'] = True  # 是否有图
    else:
        res['has_image'] = False

    if p.diary:
        if (not p.diary.is_online):
            res['is_online'] = False  # 关联日记本的帖子如果日记本下线则帖子也下线
        if p.diary.is_sink:
            res['is_sink'] = True  # 关联日记本的帖子如果日记本下沉则帖子也下沉

        res['content_level'] = p.diary.content_level
    problem_replys = p.topicreply_set.all()
    res['replys_num'] = problem_replys.count()
    res['replys'] = [{
                         'id': r.id,
                         'content': r.content,
                     } for r in problem_replys]

    last_update_time = p.last_modified
    res['last_update_time'] = tzlc(last_update_time)

    try:
        if res['replys_num'] > 0:
            problem_replys_sorted = sorted(list(problem_replys), key=lambda item: item.reply_date, reverse=True)
            res['latest_reply_time'] = tzlc(problem_replys_sorted[0].reply_date)
        else:
            res['latest_reply_time'] = res['created_time']
    except:
        res['latest_reply_time'] = res['created_time']

    popularity = 0
    popularity += problem_replys.count()
    popularity += p.votes.count()
    res['popularity'] = popularity

    res['topic_score'] = [{
                              'user_id': ts.user.id,
                              'score': ts.score,
                          } for ts in p.topic_score.all()]
    res['topic_vote_count'] = p.vote_amount
    return res
