# -*- coding: utf-8 -*-
""" 线索通 """
import json
import logging
import time

from django.conf import settings
from gm_types.doctor import DOCTOR_TITLE_TYPE
from gm_types.error import ERROR
from gm_types.gaia import DOCTOR_TYPE
from gm_types.gaia import PLATFORM_CHOICES
from gm_types.push import PUSH_INFO_TYPE, J_TYPE, AUTOMATED_PUSH, PUSH_URGENCY
from helios import RPCSystemException, RPCFaultException

from api.models import Service
from api.models import User, Doctor, Hospital
from api.models import VERIFY_CODE_TYPE
from api.tasks.sales_lead_task import get_merchant_by_doctor_id
from api.tasks.sales_lead_task import get_merchant_by_hospitla_id
from api.tasks.sales_lead_task import send_quesiton_message_task
from api.tool.image_utils import get_full_path
from api.tool.sms_tool import send_verified_code
from api.tool.user_tool import filter_user_nick_name
from api.tool.user_tool import get_user_from_context
from hippo.models import Merchant
from rpc.context import get_rpc_remote_invoker
from rpc.decorators import bind_context
from rpc.exceptions import GaiaRPCFaultException
from rpc.tool.error_code import CODES
from rpc.tool.error_code import gen
from rpc.tool.log_tool import logging_exception, info_logger
from services.custom_phone_service import PhoneService
from utils.phone import format_phone


def build_push_event_extra(phone_request_data):
    base = {
        'type': PUSH_INFO_TYPE.STATION_NOTICE,
        'data': phone_request_data
    }

    return base


@bind_context('api/sales_lead/test_gray')
def test_gray(ctx, device_id=None, unique_id=None):
    """ 灰度测试接口. """

    user = get_user_from_context(ctx)

    return {
        "device_id": device_id,
        "unique_id": unique_id,
        "user": str(user)
    }


@bind_context('api/sales_lead/station_notice_push')
def consultation_counsel_push_event(ctx, target_user_id, phone_request_data):
    '''
    线索通站内授权弹窗(自定义消息)

    新增推送类型 站内通知 type = 6

    :param: target_user_id: 接收方用户id
    :param: phone_request_data: 电话授权通知内容
    :param: time_to_live: 超时时间，单位秒，如果不传，push服务会设置为默认3天
    '''
    check_params_message = ''
    if not target_user_id:
        check_params_message = 'target_user_id不能为空'

    if check_params_message:
        raise GaiaRPCFaultException(ERROR.INVALID_PARAMS, check_params_message, None)
    alert = ""
    extra = build_push_event_extra(phone_request_data)

    platform = [PLATFORM_CHOICES.ANDROID, PLATFORM_CHOICES.IPHONE]

    log = {
        "target_user_id": target_user_id,
        "phone_request_data": phone_request_data,
        "call_timestamp": int(time.time() * 1000),
        "msg_id": ""
    }

    j_type = J_TYPE.MESSAGE

    api_endpoint = 'push2/push/user/automated_push/uids'
    rpc_invoker = get_rpc_remote_invoker()
    if not isinstance(target_user_id, list):
        target_user_id = [target_user_id]
    try:
        res = rpc_invoker[api_endpoint](
            user_ids=target_user_id,
            push_type=AUTOMATED_PUSH.STATION_NOTICE,
            platform=platform,
            alert=alert,
            extra=extra,
            push_time=int(time.time()),
            silent=False,
            urgency=PUSH_URGENCY.URGENT,
            j_type=j_type,
        ).unwrap() or {}

        logging.info("sales_lead push_event, target_user_id: {}, res: {}, extra:{}".format(
            target_user_id,
            json.dumps(res) if res else '',
            json.dumps(extra)))
    except (RPCFaultException, RPCSystemException) as e:
        log['success'] = False
        logging_exception()
        res = {}
    else:
        log['success'] = True
        log['msg_id'] = res.get('msg_id', '')

    return dict(
        code=0 if res else 1,
        data=res
    )


@bind_context('api/sales_lead/send_question_message')
def send_question_message(ctx, question_id, merchant_ids):
    user_id = ctx.session.user.id
    info_logger.info("rpc send_question_message, question_id: {0}, user_id: {1}, merchant_ids:{2}".format(
        question_id, user_id, merchant_ids
    ))

    if not user_id or not merchant_ids:
        raise

    try:
        rpc_invoker = get_rpc_remote_invoker()
        resp = rpc_invoker["qa/foreignkey/question"](question_ids=[question_id]).unwrap()
        question_title = resp[0]["title"]
    except:
        return gen(ERROR.UPDATE_FAIL)

    objs = Merchant.objects.using(settings.SLAVE_DB_NAME).select_related("doctor").filter(id__in=merchant_ids)

    content = {"text": question_title}
    for merchant in objs:
        info_logger.info(
            "send_quesiton_message_task delay, question_id: {0}, user_id: {1}, merchant_id:{2}, content:{3}".format(
                question_id, user_id, merchant.id, content
            ))
        send_quesiton_message_task.delay(user_id, merchant.doctor.user_id, content, question_id, merchant.id)


@bind_context('api/sales_lead/get_merchant_id')
def get_merchant_id(ctx, service_id=None, doctor_id=None, hospital_id=None):
    """ 电话线索核心页面停留 找到对应的 merchant_id. """

    merchant_id = None

    if doctor_id:
        merchant_id = get_merchant_by_doctor_id(doctor_id)
    elif service_id:
        service = Service.objects.filter(id=service_id).first()
        if service:
            merchant_id = get_merchant_by_doctor_id(service.doctor_id)
    elif hospital_id:
        merchant_id = get_merchant_by_hospitla_id(hospital_id)

    return {
        "merchant_id": merchant_id
    }


@bind_context('api/sales_lead/doctor_by_merchant_id')
def doctor_by_merchant_id(ctx, merchant_id):
    """ 根据商户ID获取医生信息. """

    merchant = Merchant.objects.filter(id=merchant_id).select_related("doctor").first()

    return {
        "merchant_id": merchant.id,
        "doctor_id": merchant.doctor_id,
        "doctor_name": merchant.doctor.name,
        "doctor_phone": merchant.doctor.phone
    }


@bind_context('api/sales_lead/user_info_by_user_id')
def user_info_by_user_id(ctx, user_id):
    try:
        user = User.objects.get(pk=user_id, is_active=True)
        is_doctor = Doctor.objects.filter(user_id=user_id).exists()
    except (User.DoesNotExist, ValueError):
        return gen(CODES.USER_NOT_FOUND)

    return {
        "user_id": user.id,
        "nick_name": filter_user_nick_name(user) or u'',
        "portrait": user.userextra.get_portrait() if user.userextra else '',
        "phone": user.person.phone if user.person else "",
        "city": user.userextra.get_city() if user.userextra else {},
        "is_puppet": user.person.is_puppet,
        "is_doctor": is_doctor,
    }


@bind_context('api/sales_lead/hospitals_info')
def get_hospital_info(ctx, hos_ids):
    hospitals = Hospital.objects.filter(id__in=hos_ids)

    officers = Doctor.objects.filter(
        hospital_id__in=hos_ids,
        doctor_type=DOCTOR_TYPE.OFFICER
    )

    hospital_officers_map = {
        doctor.hospital_id: doctor
        for doctor in officers
    }

    ret = []
    for hospital in hospitals:

        officer = hospital_officers_map.get(hospital.id)

        if officer:
            if officer.portrait:
                portrait = get_full_path(officer.portrait)
            else:
                portrait = get_full_path(u'img%2Fyiyuan.png')
        else:
            if hospital.portrait:
                portrait = get_full_path(hospital.portrait)
            else:
                portrait = get_full_path(u'img%2Fyiyuan.png')

        ret.append({
            'user_id': officer.user_id if officer else None,
            'doctor_id': officer.id if officer else None,
            'doctor_accept_private_msg': officer.accept_private_msg if officer else False,
            'id': hospital.id,
            'name': hospital.name,
            'portrait': portrait,
            'star': hospital.rate,
            'address': hospital.location
        })
    return ret


@bind_context('api/sales_lead/doctors_info')
def get_doctors_info(ctx, doctor_ids):
    doctors = Doctor.objects.filter(id__in=doctor_ids)
    ret = []
    for doctor in doctors:
        if doctor.title and doctor.title != "0":
            title = DOCTOR_TITLE_TYPE.getDesc(doctor.title)
        else:
            title = ""
        ret.append({
            "user_id": doctor.user_id,
            'doctor_id': doctor.id,
            'name': doctor.name,
            'portrait': get_full_path(doctor.portrait),
            'accept_private_msg': doctor.accept_private_msg,
            'star': doctor.rate,
            'title': title
        })
    return ret


@bind_context('api/sales_lead/send_question_to_hospitals')
def send_question_to_hospitals(ctx, question, doctor_ids, send_user_id=None):
    is_system = 1
    user_id = ctx.session.user.id
    if send_user_id:
        user_id = send_user_id
        is_system = 1  # 判断send_user_id置回是否系统消息
    info_logger.info("rpc send_question_to_hospitals, question: {0}, user_id: {1}, doctor_ids:{2}".format(
        question, user_id, doctor_ids
    ))

    if not user_id or not doctor_ids:
        raise

    doctors = Doctor.objects.filter(id__in=doctor_ids)

    content = {"text": question}
    for doctor in doctors:
        info_logger.info(
            "send_quesiton_message_task delay(2), question: {0}, user_id: {1}, doctor_id:{2}, target_user_id: {3}".format(
                question, user_id, doctor.id, doctor.user_id
            ))
        send_quesiton_message_task.delay(user_id, doctor.user_id, content, is_system)  # 测试暂时去掉delay


@bind_context('api/sales_lead/sms_code')
def send_sms_code(ctx, phone):
    """
    线索任务发送验证手机验证码
    """
    code_type = VERIFY_CODE_TYPE.RESERVE  # 预留手机号码分类
    phone = format_phone(phone)
    code = send_verified_code(phone, code_type)
    return gen(CODES.SUCCESS)


@bind_context('api/sales_lead/get_phone_prefix')
def get_phone_prefix(ctx, doctor_id):
    """
    获取医生代理400电话号
    """
    try:
        doctor = Doctor.objects.get(id=doctor_id)
        phone_prefix = PhoneService.get_phone_prefix(doctor.phone_ext)
        return {"phone_prefix": phone_prefix + ",," + doctor.phone_ext if phone_prefix and doctor.phone_ext else None}
    except Doctor.DoesNotExist:
        return {"phone_prefix": None}
