# -*- coding: UTF-8 -*-

from django.db import models

from gm_types.gaia import (
    DIARY_CONTENT_LEVEL, ORDER_STATUS, CASH_BACK_STATUS,
    PROBLEM_REVIEW_STATUS_CHOICES, DIARY_AUDIT_STATUS,
)

from talos.models.diary import Diary
from talos.services.user import UserService
from talos.services.doctor import DoctorService
from talos.services.order import OrderService
from talos.services.hospital import HospitalService
from talos.services.goods import GoodsService

from ..base.models import ViewModelBase


class DiaryVM(ViewModelBase):
    class Meta:
        verbose_name = u'日记本视图model'
        db_table = 'hera_vm_diary'
        app_label = 'hera'

    rel_model = Diary

    id = models.IntegerField(u'日记本id', primary_key=True)
    relobj = models.ForeignKey(Diary)
    # Diary Model中的字段
    title = models.CharField(u'标题', max_length=128, default='', db_index=True)
    created_time = models.DateTimeField(u'创建时间', db_index=True)
    last_modified = models.DateTimeField(u'最后修改时间', db_index=True)
    last_topic_add_time = models.DateTimeField(u'最后发帖时间', null=True, db_index=True)
    price = models.IntegerField(u'价格', default=0, db_index=True)
    reply_num = models.IntegerField(u'回复数量', default=0, db_index=True)
    rating = models.FloatField(u'评价', default=0, db_index=True)
    is_online = models.BooleanField(u'是否上线', default=True)
    is_real_case = models.BooleanField(u'真人案例', default=False)
    is_sink = models.BooleanField(u'是否下沉', default=False)
    operation_time = models.DateTimeField(u'手术时间', null=True, db_index=True)
    # tags
    is_headline = models.BooleanField(u'首页推荐', default=False)
    is_essence = models.BooleanField(u'精华帖', default=False)
    content_level = models.CharField(
        u'内容等级', max_length=1,
        choices=DIARY_CONTENT_LEVEL, default=DIARY_CONTENT_LEVEL.UNAUDITED,
    )
    audit_status = models.CharField(
        u'审核状态', max_length=1,
        choices=DIARY_AUDIT_STATUS, default=DIARY_AUDIT_STATUS.UNAUDITED,
    )
    audit_time = models.DateTimeField(u'最终审核时间', null=True)

    # 需要整合的字段
    not_empty = models.BooleanField(u'非空日记本', default=False)  # False: 空日记本
    not_review_topic_num = models.IntegerField(u'未审核帖子数', default=0)

    # 关联表信息
    user_id = models.IntegerField(u'用户id', db_index=True)
    user_nickname = models.CharField(u'用户昵称', max_length=30, db_index=True)
    doctor_id = models.CharField(u'医生id', max_length=100, null=True, db_index=True)
    doctor_name = models.CharField(u'医生名称', max_length=200, default='', db_index=True)
    hospital_id = models.CharField(u'医院id', max_length=100, null=True, db_index=True)
    hospital_name = models.CharField(u'医院名称', max_length=100, default='', db_index=True)
    order_id = models.CharField(u'订单id', max_length=12, null=True, db_index=True)
    order_is_self_support = models.BooleanField(u'订单自营', default=True)
    order_status = models.CharField(
        u'订单状态', max_length=20, null=True,
        choices=ORDER_STATUS, default=ORDER_STATUS.NOT_PAID,
    )
    order_cash_back_status = models.CharField(
        verbose_name=u'返现状态', max_length=1, null=True,
        choices=CASH_BACK_STATUS, default=CASH_BACK_STATUS.APPLY,
    )
    order_validated = models.BooleanField(default=False)
    order_cashback_id = models.CharField(u'返现id', max_length=15, null=True, db_index=True)
    order_cashback_time = models.DateTimeField(u'返现时间', null=True)
    service_id = models.IntegerField(u'美购id', null=True, db_index=True)
    service_name = models.CharField(u'美购名称', max_length=100, default='', db_index=True)
    service_is_online = models.BooleanField(u'美购上线', default=True)

    diaryrank_id = models.IntegerField(u'日记本首页排序分值id', null=True)
    diaryrank_additional_score = models.IntegerField(u'附加分数', default=0)

    low_quality = models.IntegerField(u'是否低质量', default=0)
    low_quality_deal = models.BooleanField(u'低质量是否处理', default=False)

    def save_from_object(self, diary):
        self.assign_object(diary)
        self.save()

    @classmethod
    def prefetch(cls, objs):
        user_ids = []
        doctor_ids = []
        hospital_ids = []
        service_ids = []
        for o in objs:
            user_ids.append(o.user_id)
            doctor_ids.append(o.doctor_id)
            hospital_ids.append(o.hospital_id)
            service_ids.append(o.service_id)
        UserService.get_users_by_user_ids(list(set(user_ids)))
        DoctorService.get_doctor_from_doctor_ids(list(set(doctor_ids)))
        HospitalService.get_hospital_from_hospital_ids(list(set(hospital_ids)))

    def assign_object(self, diary):
        self.relobj = diary
        for field in self._meta.get_fields():
            field_name = field.name
            if isinstance(field, models.fields.related.RelatedField):
                # 跳过related field
                continue
            if hasattr(diary, field_name):
                setattr(self, field_name, getattr(diary, field_name))

        user = UserService.get_user_by_user_id(diary.user_id)
        self.user_nickname = getattr(user, 'nickname', '')

        doctor = DoctorService.get_doctor_from_doctor_id(diary.doctor_id)
        self.doctor_name = getattr(doctor, 'name', '')

        hospital = HospitalService.get_hospital_from_hospital_id(diary.hospital_id)
        self.hospital_name = getattr(hospital, 'name', '')

        order = OrderService.get_order_from_order_id(diary.order_id)
        if order:
            self.order_is_self_support = getattr(order, 'is_self_support', True)
            self.order_status = getattr(order, 'status', None)
            self.order_cash_back_status = getattr(order, 'cash_back_status', None)
            self.order_validated = getattr(order, 'validated', False)
            self.order_cashback_id = order.cashback_id
            self.order_cashback_time = order.cashback_time

        service = GoodsService.get_service_by_service_id(diary.service_id)
        self.service_name = getattr(service, 'name', '')
        self.service_is_online = getattr(service, 'is_online', True)

        if hasattr(self.relobj, 'diary_rank'):
            self.diaryrank_id = self.relobj.diary_rank.id
            self.diaryrank_additional_score = self.relobj.diary_rank.additional_score

        # 整合数据
        self.not_empty = self.relobj.topics.filter(is_online=True).exists()
        self.not_review_topic_num = self.relobj.topics.filter(
            review_status=PROBLEM_REVIEW_STATUS_CHOICES.NOT_REVIEW,
            is_online=True,
        ).count()

        # tags
        diary_tags = set([tag.id for tag in diary.tags])
        vm_tags = set([rel.tag_id for rel in self.rel_tags.all()])
        DiaryTagsVM.objects.bulk_create(
            [DiaryTagsVM(diary_id=self.id, tag_id=tid) for tid in (diary_tags - vm_tags)]
        )
        DiaryTagsVM.objects.filter(
            diary_id=self.id, tag_id__in=list(vm_tags - diary_tags),
        ).delete()


class DiaryTagsVM(ViewModelBase):
    class Meta:
        verbose_name = u'日记本Tag关联'
        db_table = 'hera_vm_diary_tags'
        app_label = 'hera'

    diary = models.ForeignKey(DiaryVM, related_name='rel_tags')
    tag_id = models.IntegerField(u'Tag id')
