# coding=utf8

from __future__ import unicode_literals, absolute_import, print_function

import json

from gmgql import execute

from talos.services.base import ServiceBase
from talos.services.base import RpcServiceModelCache
from talos.cache.base import talos_rpc_service_model_cache
from talos.services.models.doctor import Doctor
from talos.services.user import UserService


class DoctorService(ServiceBase):
    _model_name = 'doctor_v2'

    __cached_layer = RpcServiceModelCache(talos_rpc_service_model_cache, _model_name)

    @classmethod
    def _generate_doctor_object_from_rpc_doctor_data(cls, result):
        if not result:
            return []

        doctors = []
        for r in result:
            r.update({
                'id': r['doctor']['id'],
                'reply_limit': r['doctor']['reply_limit'],
                'is_online': r['doctor']['is_online'],
                'doctor_type': r['doctor']['doctor_type'],
                'portrait': r['doctor']['portrait'],
                'name': r['doctor']['name'],
                'phone': r['doctor']['phone'],
                'user_id': r['id'],
                'hospital_id': r['doctor']['hospital'] and r['doctor']['hospital']['id'] or None,
            })

            if r['doctor']['hospital']:
                r['hospital'] = {
                    'id': r['doctor']['hospital']['id'],
                    'name': r['doctor']['hospital']['name'],
                    'city_tag_id': (
                        r['doctor']['hospital']['city'] and
                        r['doctor']['hospital']['city']['tag'] and
                        r['doctor']['hospital']['city']['tag']['id'] or None
                    ),
                    'province_tag_id': (
                        r['doctor']['hospital']['city'] and
                        r['doctor']['hospital']['city']['province'] and
                        r['doctor']['hospital']['city']['province']['tag'] and
                        r['doctor']['hospital']['city']['province']['tag']['id'] or None
                    ),
                    'country_tag_id': (
                        r['doctor']['hospital']['city'] and
                        r['doctor']['hospital']['city']['province'] and
                        r['doctor']['hospital']['city']['province']['country'] and
                        r['doctor']['hospital']['city']['province']['country']['tag'] and
                        r['doctor']['hospital']['city']['province']['country']['tag']['id'] or None
                    ),
                }

                # delete doctor
                del r['doctor']

            d = Doctor.from_dict(r)
            if d:
                doctors.append(d)

        return doctors

    @classmethod
    def _cache_doctor(cls, doctor):
        v = doctor.to_json()
        cls.__cached_layer.set(doctor.id, v, 60 * 60)

    @classmethod
    def _get_doctor_from_cache_by_ids(cls, doctor_ids):
        cached_info = cls.__cached_layer.mget(doctor_ids)

        result = []

        missing = cached_info.pop(cls.__cached_layer.missing_k)
        if missing:
            query = '''query {
                doctors(pk__in:%s) {
                    id
                    is_online
                    doctor_type
                    portrait
                    name
                    phone
                    reply_limit
                    user {
                        id
                    }
                    hospital {
                      id
                      name
                      city {
                          tag {
                              id
                          }
                          province {
                              tag {
                                  id
                              }
                              country {
                                  tag {
                                      id
                                  }
                              }
                          }
                      }
                    }
                }
            }
            '''
            query = query % json.dumps(missing)
            schema = cls.get_gaia_graph_scheme()
            res = execute(schema, request_string=query)
            if not res.errors:
                r = res.data['doctors']
                for info in r:
                    info['user_id'] = info['user'] and info['user']['id'] or None
                    info['hospital_id'] = info['hospital'] and info['hospital']['id'] or None
                    info['hospital'] = {
                        'id': info['hospital'] and info['hospital']['id'] or None,
                        'name': info['hospital'] and info['hospital']['name'] or None,
                        'city_tag_id': (
                            info['hospital']['city'] and
                            info['hospital']['city']['tag'] and
                            info['hospital']['city']['tag']['id'] or None
                        ),
                        'province_tag_id': (
                            info['hospital']['city'] and
                            info['hospital']['city']['province'] and
                            info['hospital']['city']['province']['tag'] and
                            info['hospital']['city']['province']['tag']['id'] or None
                        ),
                        'country_tag_id': (
                            info['hospital']['city'] and
                            info['hospital']['city']['province'] and
                            info['hospital']['city']['province']['country'] and
                            info['hospital']['city']['province']['country']['tag'] and
                            info['hospital']['city']['province']['country']['tag']['id'] or None
                        ),
                    }

                    doctor = Doctor.from_dict(info)
                    if not doctor:
                        continue

                    result.append(doctor)
                    cls._cache_doctor(doctor)

        for k in cached_info:
            i = cached_info[k]
            v = json.loads(i)
            h = Doctor.from_dict(v)
            result.append(h)

        return result

    @classmethod
    def get_doctor_from_doctor_id(cls, id):
        if id is None:
            return None

        result = cls.get_doctor_from_doctor_ids(ids=[id])
        if not result:
            return

        return result[0]

    @classmethod
    def get_doctor_from_doctor_ids(cls, ids):
        return cls._get_doctor_from_cache_by_ids(ids)

    @classmethod
    def get_doctor_by_user_id(cls, user_id):
        if user_id is None:
            return None

        result = cls.get_doctor_from_user_ids(user_ids=[user_id])
        return result[0]

    @classmethod
    def doctor_can_create_topic(cls, user_id=None, doctor_id=None):
        if user_id is None and doctor_id is None:
            return False
        kw = {
            'user_id': user_id,
            'doctor_id': doctor_id,
        }
        kw['id'] = kw.pop('doctor_id')      # 这么做的原因为对面接口的参数字段名就是这样的

        try:
            result = cls.call_rpc('api/doctor/can_create_topic', **kw)

        except Exception:
            return True

        return result['can_create_topic']

    @classmethod
    def get_discount_score_for_diary_index(cls, doctor_id):
        if doctor_id is None:
            return 0.0
        try:
            result = cls.call_rpc('api/doctor/diary_index_discount_score', id=doctor_id)

        except Exception:
            return 0.0

        return result

    @classmethod
    def get_doctor_from_context(cls, ctx):
        user = UserService.get_user_from_context(ctx)
        if user:
            return cls.get_doctor_by_user_id(user.id)
        else:
            return None

    @classmethod
    def get_doctor_from_user_ids(cls, user_ids):
        query = '''query {
            users(pk__in:%s) {
                id
                doctor {
                  id
                  is_online
                  doctor_type
                  portrait
                  name
                  phone
                  reply_limit
                  hospital {
                    id
                    name
                    city {
                        tag {
                            id
                        }
                        province {
                            tag {
                                id
                            }
                            country {
                                tag {
                                    id
                                }
                            }
                        }
                    }
                  }
                }
            }
        }
        '''
        user_ids = [int(i) for i in user_ids if i]
        if not user_ids:
            return []

        query = query % json.dumps(user_ids)
        schema = cls.get_gaia_graph_scheme()
        res = execute(schema, request_string=query)
        if res.errors:
            return []

        _result = res.data['users']
        result = []
        for r in _result:
            if not r['doctor']:
                continue

            result.append(r)

        return cls._generate_doctor_object_from_rpc_doctor_data(result)

    @classmethod
    def if_person_is_doctor(cls, person_id):
        try:
            result = cls.call_rpc('api/person/if_person_is_doctor', person_id=person_id)
            return result
        except Exception:
            return False
