# coding=utf-8
import datetime
from django.contrib.auth.models import User
from django.db import models, transaction
from gm_types.gaia import PAYMENT_CHANNEL, ORDER_SOURCE, ORDER_STATUS, SETTLEMENT_STATUS, ORDER_OPERATION_TYPE, \
    ORDER_OPERATION_ROLE
from gm_upload import ImgUrlField, IMG_TYPE

from api.models import Doctor, Hospital, Person
from api.models import Hospital, PeriodHospital
from services.custom_phone_service import PhoneService
from rpc.tool.error_code import CODES, gen


class MaidanOrder(models.Model):
    class Meta:
        verbose_name = u'买单订单信息'
        verbose_name_plural = u'买单订单信息'
        db_table = u'maidan_order'
        app_label = u'maidan'

    id = models.CharField(max_length=12, verbose_name=u'买单订单号', primary_key=True)
    maidan_name = models.CharField(verbose_name=u'买单名称', max_length=100, null=False)
    tag_names = models.CharField(verbose_name=u'标签名称', max_length=100, null=False)

    status = models.CharField(max_length=20, choices=ORDER_STATUS, default=ORDER_STATUS.NOT_PAID, null=False,
                              verbose_name=u'订单状态')

    maidan_price_cent = models.IntegerField(verbose_name=u'订单总价')
    payment_cent = models.IntegerField(verbose_name=u'付款额')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=u"创建时间")

    payment_id = models.CharField(max_length=20, null=False, verbose_name=u'支付Id')
    payment_channel = models.CharField(max_length=3, choices=PAYMENT_CHANNEL, default='', verbose_name=u'支付渠道')
    payment_time = models.DateTimeField(null=True, verbose_name=u'网关付款时间')

    # 用户相关信息
    user = models.ForeignKey(User, verbose_name=u'用户')

    source = models.CharField(
        max_length=1, choices=ORDER_SOURCE, default=ORDER_SOURCE.UNKNOW,
        blank=True, verbose_name=u'订单来自哪个平台[iOS, Android, Web]'
    )

    # 商家结账相关
    is_settled = models.BooleanField(help_text=u'是否已结算', verbose_name=u'是否已结算', default=False)
    settled_time = models.DateTimeField(null=True, blank=True, verbose_name=u'结算时间')

    doctor = models.ForeignKey(Doctor, verbose_name=u'所属医生', null=False, on_delete=models.DO_NOTHING)

    doctor_discount_rate = models.IntegerField(verbose_name=u'医生设置的折扣比例')
    doctor_discount_cent = models.IntegerField(verbose_name=u'医生设置的折扣金额')
    gengmei_offers_rate = models.IntegerField(verbose_name=u'更美承担优惠比例', default=0)
    gengmei_offers_cent = models.IntegerField(verbose_name=u'更美承担优惠金额', default=0)
    discount_cent = models.IntegerField(verbose_name=u'抽成', default=0)
    settle_price_cent = models.IntegerField(verbose_name=u'结算金额', default=0)

    def operate(self, operator, optype, role, source=ORDER_SOURCE.UNKNOW):
        func = order_operate_map.get(optype)
        if func:
            try:
                with transaction.atomic():
                    func(self)
                    self.save()
                    MaidanOrderOperation.objects.create(order=self, operator=operator, optype=optype, role=role,
                                                        source=source,
                                                        operate_at=datetime.datetime.now())
                    # TODO: 找出所有使用了is_success, 去掉
                    return True
            except Exception as e:
                raise e
        else:
            raise Exception("order operation not support")

    @property
    def payment_info(self):
        maidan_payment = None
        try:
            maidan_payment = MaidanPayment.objects.get(pk=self.payment_id)
        except MaidanPayment.DoesNotExist:
            pass

        result = {
            "payment_channel": self.payment_channel,
            "payment_id": self.payment_id,
            "transaction_id": "",
            "payment_cent": self.payment_cent,
            "payment_time": None,
        }

        if maidan_payment:
            result["transaction_id"] = maidan_payment.channel_transaction_id
            result["payment_time"] = maidan_payment.payment_time

        return result

    @property
    def rebate(self):
        # 订单折扣
        return self.doctor_discount_rate - self.gengmei_offers_rate

    def order_data(self):
        maidansnapshot = self.maidansnapshot
        if self.status == ORDER_STATUS.PAID:
            call_url = ''
            doctor_phone_ext = self.doctor.phone_ext
            doctor_phone_ext = doctor_phone_ext.strip()
            if doctor_phone_ext:
                call_url = 'tel://' + PhoneService.get_phone_num(doctor_phone_ext)

            # 资质显示
            show_lincence = self.doctor.get_doctor_lincence(self.doctor.title, 0)

            order_data = {
                "accept_private_msg": maidansnapshot.doctor.accept_private_msg,
                'city': maidansnapshot.doctor.hospital.city.name,
                "show_location": maidansnapshot.doctor.show_location,
                "doctor": maidansnapshot.doctor.name,
                "doctor_id": maidansnapshot.doctor.id,
                "doctor_type": maidansnapshot.doctor.doctor_type,
                "doctor_user_id": maidansnapshot.doctor.user.id,
                "doctor_portrait": maidansnapshot.doctor_portrait,
                "hospital": maidansnapshot.hospital.name,
                "hospital_id": maidansnapshot.hospital_id,
                'hospital_lat': maidansnapshot.hospital.baidu_loc_lat,
                'hospital_lng': maidansnapshot.hospital.baidu_loc_lng,
                'address': maidansnapshot.hospital.location,
                "order_id": self.id,
                "call_url": call_url,
                "order_name": self.maidan_name,
                'phone': call_url,
                'status': self.status,
                'total_price': self.maidan_price_cent / 100,
                'gengmei_price': self.payment_cent / 100,
                'show_v': show_lincence['show_v'],
                'payment_date': self.payment_time.strftime('%Y-%m-%d %H:%M'),
                'is_support_maidan_installment': self.is_support_installment
            }
        elif self.status == ORDER_STATUS.NOT_PAID or self.status == ORDER_STATUS.PAYING:
            order_data = {
                "order_id": self.id,
                'status': ORDER_STATUS.NOT_PAID,
                'order_name': self.maidan_name,
                'doctor_portrait': self.doctor.portrait,
                'address': self.doctor.hospital.location,
                'gengmei_price': self.payment_cent / 100,
                'total_price': self.maidan_price_cent / 100,
                'discount': self.doctor_discount_rate - self.gengmei_offers_rate,
                'is_support_maidan_installment': self.is_support_installment
            }
        else:
            return gen(CODES.ORDER_NOT_FOUND)
        return order_data

    @property
    def is_support_installment(self):
        try:
            price = self.payment_cent / 100
            if PeriodHospital.check_hospital_in_list(self.doctor.hospital) and 500 <= price <= 60000:
                return True
        except:
            return False
        else:
            return False


class MaidanOrderSnapshot(models.Model):
    class Meta:
        verbose_name = u'买单订单快照'
        verbose_name_plural = u'买单订单快照'
        db_table = u'maidan_ordersnapshot'
        app_label = u'maidan'

    maidan_order = models.OneToOneField(MaidanOrder, related_name=u'maidansnapshot')

    maidan_name = models.CharField(verbose_name=u'买单名称', max_length=100, null=False)
    tag_names = models.CharField(verbose_name=u'标签名称', max_length=100, null=False)
    doctor_portrait = ImgUrlField(max_length=300, help_text=u'医生头像', verbose_name=u'图片地址', default='',
                                  img_type=IMG_TYPE.DOCTOR)

    maidan_price_cent = models.IntegerField(verbose_name=u'订单总价')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=u"创建时间")

    # 用户相关信息
    user = models.ForeignKey(User, verbose_name=u'用户')

    source = models.CharField(
        max_length=1, choices=ORDER_SOURCE, default=ORDER_SOURCE.UNKNOW,
        blank=True, verbose_name=u'订单来自哪个平台[iOS, Android, Web]'
    )

    doctor = models.ForeignKey(Doctor, verbose_name=u'所属医生', null=False, on_delete=models.DO_NOTHING)

    doctor_discount_rate = models.IntegerField(verbose_name=u'医生设置的折扣比例')
    doctor_discount_cent = models.IntegerField(verbose_name=u'医生设置的折扣金额')
    gengmei_offers_rate = models.IntegerField(verbose_name=u'更美承担优惠比例', default=0)
    gengmei_offers_cent = models.IntegerField(verbose_name=u'更美承担优惠金额', default=0)
    discount_rate = models.IntegerField(verbose_name=u'抽成比例', default=0)

    hospital = models.ForeignKey(Hospital, verbose_name=u'关联的医院', null=True, on_delete=models.DO_NOTHING)
    business_partner = models.ForeignKey(User, default=None, null=True, verbose_name=u'售出商务',
                                         on_delete=models.DO_NOTHING, related_name='maidansnapshot_business')


class MaidanPayment(models.Model):
    class Meta:
        verbose_name = u'买单支付信息'
        verbose_name_plural = u'买单支付信息'
        db_table = u'maidan_payment'
        app_label = u'maidan'

    id = models.CharField(max_length=30, verbose_name=u'Id', primary_key=True)
    out_trade_no = models.CharField(max_length=64, verbose_name='商户的支付id')

    name = models.CharField(verbose_name=u'买单名称', max_length=100, null=False)
    total_amount_cent = models.IntegerField(verbose_name=u'付款额')

    maidan_order_id = models.CharField(max_length=30, db_index=True, verbose_name=u'买单订单号')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name=u"创建时间")
    expired_at = models.DateTimeField(auto_now_add=True, verbose_name=u"过期时间")

    status = models.CharField(
        max_length=3, choices=SETTLEMENT_STATUS, default=SETTLEMENT_STATUS.NOT_PAID,
        null=False, verbose_name=u'付款状态'
    )
    payment_time = models.DateTimeField(null=True, verbose_name=u'网关付款时间')

    channel = models.CharField(max_length=3, choices=PAYMENT_CHANNEL, default='', verbose_name=u'支付渠道')
    channel_transaction_id = models.CharField(max_length=50, null=False, db_index=True, verbose_name=u'支付交易Id')
    notify_info = models.TextField(default=u'', verbose_name=u'支付通知信息快照')


class MaidanOrderOperation(models.Model):
    class Meta:
        verbose_name = u'买单支付信息'
        verbose_name_plural = u'买单支付信息'
        db_table = u'maidan_order_operation'
        app_label = u'maidan'

    order = models.ForeignKey(MaidanOrder)
    operator = models.ForeignKey(Person)
    optype = models.IntegerField(verbose_name=u'目标类型', choices=ORDER_OPERATION_TYPE,
                                 default=ORDER_OPERATION_TYPE.CREATE)
    role = models.IntegerField(verbose_name=u'操作角色', choices=ORDER_OPERATION_ROLE, default=ORDER_OPERATION_ROLE.USER)
    source = models.CharField(
        max_length=1, choices=ORDER_SOURCE, default=ORDER_SOURCE.UNKNOW,
        blank=True, verbose_name=u'操作来自哪个平台[iOS, Android, Web]'
    )
    operate_at = models.DateTimeField(null=True, blank=True, verbose_name=u'操作时间')


def order_pay(order):
    if order.status in (ORDER_STATUS.NOT_PAID, ORDER_STATUS.PAYING, ORDER_STATUS.CANCEL):
        order.status = ORDER_STATUS.PAID
        return
    raise gen(CODES.ORDER_PAY_STATUS_ERROR)


def order_cancel(order):
    if order.status not in (ORDER_STATUS.NOT_PAID, ORDER_STATUS.PAYING):
        raise gen(CODES.ORDER_CAN_NOT_CANCEL)

    # 未付款订单可直接取消
    order.status = ORDER_STATUS.CANCEL


def order_not_paid(order):
    order.status = ORDER_STATUS.NOT_PAID


def order_paying(order):
    order.status = ORDER_STATUS.PAYING


# 已经在上一层增加了, transaction.atomic() 不要在函数里再加了
order_operate_map = {
    ORDER_OPERATION_TYPE.PAY: order_pay,
    ORDER_OPERATION_TYPE.CANCEL: order_cancel,
    ORDER_OPERATION_TYPE.NOT_PAID: order_not_paid,
    ORDER_OPERATION_TYPE.PAYING: order_paying,
}
