# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function

from django.db import models
from django.db.models import F

from gm_types.gaia import SERVICE_ITEM_PRICE_TYPE, DOCTOR_TYPE

from api.tool.datetime_tool import get_timestamp
from api.models import Service, ServiceItem
from api.models import Person, Doctor


class Shopcart(models.Model):
    class Meta:
        verbose_name = u'购物车'
        db_table = 'api_shopcart'
        app_label = 'api'
        unique_together = [
            ('person', 'service'),
        ]

    person = models.ForeignKey(Person, verbose_name=u'用户')
    service = models.ForeignKey(Service, verbose_name=u'美购')
    # service_item_key related to field key in model ServiceItem
    # service_item_key = models.CharField(max_length=64, blank=True, verbose_name=u'美购多属性', null=True)
    added_at = models.DateTimeField(auto_now_add=True, verbose_name=u"加入购物车时间")
    service_item = models.ForeignKey(ServiceItem)
    number = models.IntegerField('购买数量', default=1)

    gengmei_price_at_add = models.IntegerField(verbose_name=u'更美价', default=0)
    gengmei_price_at_last_push = models.IntegerField(verbose_name=u'更美价', default=0)

    update_time = models.DateTimeField(auto_now=True)

    @staticmethod
    def get_shopcart_info_list(shopcart_items):
        from api.manager.service_info_manager import get_sku_id_to_sku_name_info

        # 需要基于SKU去重
        result = []

        unique_service_item_id = set()

        all_service_item_id = [i.service_item_id for i in shopcart_items if i.service_item_id]

        service_item_id_to_obj = {si.id: si for si in
                                  ServiceItem.objects.select_related('service__project_type').filter(id__in=all_service_item_id)}

        all_doctor_ids = set([si.service.doctor_id for _, si in service_item_id_to_obj.items()])

        doctor_id_to_data = {d[0]: d for d in
                             Doctor.objects.filter(id__in=all_doctor_ids).values_list('id', 'doctor_type', 'name',
                                                                                      'hospital_id', 'hospital__name')}

        service_item_id_to_items_name = ServiceItem.get_items_name(all_service_item_id)
        service_item_id_to_sku_name_info = get_sku_id_to_sku_name_info(all_service_item_id)

        # 普通医生：“医生姓名”  “医生所属医院”
        # 机构管理者：“医生姓名”

        for cart_item in shopcart_items:

            if cart_item.service_item_id and cart_item.service_item_id in service_item_id_to_obj and \
                            cart_item.service_item_id not in unique_service_item_id:
                unique_service_item_id.add(cart_item.service_item_id)

                service_item = service_item_id_to_obj[cart_item.service_item_id]

                is_child = False
                if service_item.parent_id:
                    is_child = True
                price_info_child = service_item.get_current_price_info(is_child=is_child) or {}
                price_info = price_info_child

                gengmei_price_change = 0
                if price_info and cart_item.gengmei_price_at_add > 0:
                    change = cart_item.gengmei_price_at_add - service_item.gengmei_price
                    if change > 0:
                        gengmei_price_change = change

                service_can_sold = service_item.service.is_can_be_sold()
                service_item_has_stock = service_item.sku_stock > 0

                # 添加失效判断
                if is_child:
                    shopcart_item_can_sold = bool(service_can_sold and service_item_has_stock and price_info and service_item.get_special_valid_status())
                else:
                    shopcart_item_can_sold = bool(service_can_sold and service_item_has_stock and price_info)

                if is_child and not price_info_child:
                    pre_payment_price = service_item.get_default_price_info().get('pre_payment_price')
                else:
                    pre_payment_price = service_item.pre_payment_price

                service_item_names = service_item_id_to_items_name.get(cart_item.service_item_id, '')
                if service_item.parent_id:
                    if service_item.get_more_buy_count():
                        service_item_names = service_item.items_name
                        service_item_names.insert(0, str(service_item.get_more_buy_count()) + '次')

                buy_limit = service_item.get_buy_limit()
                number = cart_item.number if 0 < cart_item.number <= buy_limit else buy_limit

                is_seckill = price_info.get('price_type') == SERVICE_ITEM_PRICE_TYPE.SECKILL

                doctor_id = service_item.service.doctor_id
                _, doctor_type, doctor_name, hospital_id, hospital_name = doctor_id_to_data[doctor_id]

                service_name = service_item.service.name

                if str(cart_item.service_item_id) in service_item_id_to_sku_name_info:
                    sku_name_info = service_item_id_to_sku_name_info[str(cart_item.service_item_id)]

                    service_obj = service_item.service
                    service_item_names = [sku_name_info["name"]] if sku_name_info["name"] else []
                    # 735 sku标准化2.0
                    if sku_name_info.get('project_type_name'):
                        service_name = "【{}】{}".format(
                            sku_name_info.get('project_type_name'), service_obj.short_description
                        )
                    else:
                        service_name = "【{}】{}".format(
                            service_obj.project_type.name, service_obj.short_description
                        )

                data = {
                    'id': cart_item.id,
                    'service_item_id': cart_item.service_item_id,
                    'service_id': cart_item.service_id,
                    'service_image_header': service_item.service.image_header,
                    # Picture.get_thumb_path(item['service__image_header'] or ''),
                    'service_name': service_name,  # item['service__name'],
                    # 'options_desc': options_desc,
                    'service_item_names': service_item_names,
                    'pre_payment_price': pre_payment_price,  # str(pre_payment_price),
                    'number': number,  # str(item['number']),
                    'gengmei_price_change': gengmei_price_change,
                    'buy_limit': buy_limit,  # int(item['buy_limit'] or 1),
                    'is_seckill': is_seckill,  # item['is_seckill'],
                    'shopcart_item_can_sold': shopcart_item_can_sold,
                    'doctor_id': doctor_id,
                    'doctor_type': doctor_type,
                    'doctor_name': doctor_name,
                    'hospital_id': hospital_id,
                    'hospital_name': hospital_name,
                    'order_sku_name': service_item.order_show_name(),
                }
                result.append(data)

        return result

    @staticmethod
    def add_or_create(person_id, service_id, service_item_id, number, service_item_gengmei_price, now):
        update_count = Shopcart.objects.filter(
            person_id=person_id, service_item_id=service_item_id
        ).update(
            number=number + F('number'), update_time=now,
            gengmei_price_at_add=service_item_gengmei_price,
            gengmei_price_at_last_push=service_item_gengmei_price,
        )

        if not update_count:
            Shopcart.objects.create(
                person_id=person_id, service_id=service_id,
                service_item_id=service_item_id, number=number,
                gengmei_price_at_add=service_item_gengmei_price,
                gengmei_price_at_last_push=service_item_gengmei_price,
            )
