# coding:utf8
from django.db import models
from django.db.models import Q

from api.tool.geo_tool import calc_distances_by_lat_lnt, display_distances
from .special import Special
from gm_upload import ImgUrlField, IMG_TYPE
from gm_types.gaia import RANK_LIST_TYPE, RANKBOARD_TYPE, HOSPITAL_TYPE, DOCTOR_TYPE, WORLD_AREA_TYPE
from gm_types.gaia import RANKBOARD_DATA_TYPE
from api.models import Region, City, Tag, Share
from api.models import Service, Hospital, Doctor


class RankList(models.Model):
    class Meta:
        verbose_name = u'排行榜'
        app_label = u'api'

    name = models.CharField(verbose_name=u'排行榜名称', max_length=128)
    rank_type = models.CharField(verbose_name=u'排行榜类型', max_length=8, choices=RANK_LIST_TYPE)
    image = ImgUrlField(img_type=IMG_TYPE.SPECIAL, max_length=300, verbose_name=u'排行榜头图', blank=True, null=True)
    is_online = models.BooleanField(verbose_name=u'是否上线', default=False)
    rank = models.IntegerField(verbose_name=u'排序', default=999)
    special = models.ForeignKey(Special, verbose_name=u'关联专题')
    services = models.ManyToManyField(Service, verbose_name=u'排行美购', through=u'RankListService')


class RankListService(models.Model):
    class Meta:
        verbose_name = u'排行榜关联美购'
        app_label = u'api'

    rank_list = models.ForeignKey(RankList, verbose_name=u'管理专题排行榜')
    service = models.ForeignKey(Service, verbose_name=u'关联美购')
    message = models.CharField(verbose_name=u'一句话描述', default=u'', max_length=128)
    rank = models.IntegerField(verbose_name=u'排序', default=9999)


class RankBoard(models.Model):
    class Meta:
        verbose_name = u'客户端榜单'
        app_label = u'api'

    title = models.CharField(verbose_name=u'榜单名称', max_length=30)
    image = ImgUrlField(img_type=IMG_TYPE.NOWATERMARK, verbose_name=u'主题banner', max_length=300)
    type = models.CharField(choices=RANKBOARD_TYPE, verbose_name=u'排行榜类型', max_length=2)
    describe = models.CharField(verbose_name=u'榜单描述', max_length=200)
    rank = models.IntegerField(verbose_name=u'展示顺序')
    is_online = models.BooleanField(verbose_name=u'是否上线')
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    datapool_last_modified = models.DateTimeField(verbose_name=u'最后一次获取数据时间', blank=True, null=True, default=None)
    share = models.ForeignKey(Share, verbose_name=u'分享相关')
    show_regions = models.ManyToManyField(Region, verbose_name=u'展示大区', through=u'RankboardShowRegion')
    show_cities = models.ManyToManyField(City, verbose_name=u'展示城市', through=u'RankboardShowCity',
                                         related_name=u'rankboard_showcity')
    data_tags = models.ManyToManyField(Tag, verbose_name=u'榜单数据来源标签', through=u'RankboardDataTag')
    to_rankboards = models.ManyToManyField(u'self', verbose_name=u'榜单关联榜单', through=u'RankboardConnect',
                                           symmetrical=False)

    def get_related_data(self):
        return {
            'id': self.id,
            'type': self.get_rank_type(),
            'title': self.title
        }

    def get_data_for_backend(self):
        return {
            'id': self.id,
            'title': self.title,
            'image_url': self.get_icon_url(),
            'url': '',
            'type': self.type,
            'banner': self.image,
            'desc': self.describe
        }

    def get_rank_type(self):
        if self.type == RANKBOARD_TYPE.DOCTOR:
            return 'expert'
        elif self.type == RANKBOARD_TYPE.SERVICE:
            return 'service'
        elif self.type == RANKBOARD_TYPE.HOSPITAL:
            return 'organization'
        else:
            return 'unknow'

    def get_icon_url(self):
        return 'https://heras.igengmei.com/2018/01/18/acb8f5dbc0'

    @classmethod
    def build_no_city_query(cls):
        return Q(show_regions__isnull=True) & Q(show_cities__isnull=True)

    @classmethod
    def build_city_query(cls, city_id):
        if city_id in WORLD_AREA_TYPE:
            return None
        try:
            city = City.objects.get(id=city_id)
            if getattr(city, 'province'):
                region = city.province.region
                province_id = city.province.id
                if province_id:
                    # 选北京显示朝阳,选朝阳显示北京
                    query = (
                        Q(show_cities__province_id=city_id) |
                        Q(show_cities=city_id) |
                        Q(show_cities=province_id)
                    )
                    query_city_slide = query
                else:
                    query = (
                        Q(show_cities__province_id=city_id) |
                        Q(show_cities=city_id)
                    )
                    query_city_slide = query
                if region:
                    query_city_slide = query_city_slide | Q(show_regions=region)
                return query_city_slide
        except City.DoesNotExist:
            return None

    def city_tag_ids(self):
        _cities = []
        _cities.extend(self.show_cities.all())
        _cities_tag_id = [city.tag.id for city in _cities]
        _cities_tag_id = list(set(_cities_tag_id))
        return _cities_tag_id

    def region_city_tag_ids(self):
        _cities = []
        regions = self.show_regions.all()
        for region in regions:
            _cities.extend(region.cities())
        _cities_tag_id = [city.tag.id for city in _cities]
        _cities_tag_id = list(set(_cities_tag_id))
        return _cities_tag_id



class RankboardShowRegion(models.Model):
    class Meta:
        verbose_name = u'榜单展示大区'
        app_label = u'api'

    rankboard = models.ForeignKey(RankBoard)
    region = models.ForeignKey(Region)


class RankboardShowCity(models.Model):
    class Meta:
        verbose_name = u'榜单展示城市'
        app_label = u'api'

    rankboard = models.ForeignKey(RankBoard)
    city = models.ForeignKey(City)


class RankboardDataTag(models.Model):
    class Meta:
        verbose_name = u'榜单数据来源城市'
        app_label = u'api'

    rankboard = models.ForeignKey(RankBoard)
    tag = models.ForeignKey(Tag)


class RankboardConnect(models.Model):
    class Meta:
        verbose_name = u'榜单关联榜单'

    rankboard = models.ForeignKey(RankBoard)
    to_rankboard = models.ForeignKey(RankBoard, verbose_name=u'被关联榜单', related_name=u'to_connect')


class RankboardData(models.Model):
    class Meta:
        verbose_name = u'榜单数据'

    rankboard = models.ForeignKey(RankBoard)
    hospital = models.ForeignKey(Hospital, blank=True, null=True, default=None)
    service = models.ForeignKey(Service, blank=True, null=True, default=None)
    doctor = models.ForeignKey(Doctor, blank=True, null=True, default=None)
    status = models.CharField(verbose_name=u'榜单数据状态', max_length=2, choices=RANKBOARD_DATA_TYPE,
                              default=RANKBOARD_DATA_TYPE.NORMAL)
    describe = models.CharField(verbose_name=u'一句话描述', max_length=100, default=u'')
    rank = models.IntegerField(verbose_name=u'排序', default=0)

    def get_doctor_data(self, lat=0, lon=0):
        return {
            'id': self.doctor_id,
            'name': self.doctor.name,
            'title': '',
            'hospital': self.doctor.hospital.name if self.doctor.doctor_type == DOCTOR_TYPE.DOCTOR else '',
            'portrait': self.doctor.portrait + '-thumb',
            'distance': display_distances(calc_distances_by_lat_lnt(lat, lon,
                                                                    self.doctor.hospital.baidu_loc_lat,
                                                                    self.doctor.hospital.baidu_loc_lng)),
            'tags': self.doctor.get_doctor_tags()[:3],
            'star': self.doctor.rate,
            'appoint_count': self.doctor.sell_amount_display(),
            'desc': self.describe
        }

    def get_hospital_data(self, lat=0, lon=0):
        return {
            'id': self.hospital_id,
            'name': self.hospital.name,
            'title': HOSPITAL_TYPE.getDesc(self.hospital.hospital_type),
            'image': self.hospital.get_hospital_portrait() + '-thumb',
            'distance': display_distances(calc_distances_by_lat_lnt(lat, lon,
                                                                    self.hospital.baidu_loc_lat,
                                                                    self.hospital.baidu_loc_lng)),
            'tags': self.hospital.get_hospital_tags()[:3],
            'star': self.hospital.rate,
            'appoint_count': self.hospital.sell_amount_display(),
            'desc': self.describe
        }

    def get_service_data(self, lat=0, lon=0):
        return {
            'id': self.service_id,
            'short_desc': self.service.show_name,
            'doctor': self.service.doctor.name,
            'hospital': self.service.doctor.hospital.name if self.service.doctor.doctor_type == DOCTOR_TYPE.DOCTOR else '',
            'image': self.service.image_header + '-thumb',
            'distance': display_distances(calc_distances_by_lat_lnt(lat, lon,
                                                                    self.service.doctor.hospital.baidu_loc_lat,
                                                                    self.service.doctor.hospital.baidu_loc_lng)),
            'star': self.service.rating,
            'tags': self.service.doctor.hospital.get_hospital_tags()[:3],
            'price': self.service.lowest_gengmei_price,
            'is_price_range': self.service.is_multiattribute,
            'desc': self.describe
        }

    def get_data(self, lat=0, lon=0):
        if hasattr(self, 'hospital') and self.hospital:
            return self.get_hospital_data(lat, lon)
        if hasattr(self, 'doctor') and self.doctor:
            return self.get_doctor_data(lat, lon)
        if hasattr(self, 'service') and self.service:
            return self.get_service_data(lat, lon)
        return []


class RankBoardBatch(models.Model):
    class Meta:
        verbose_name = u'聚合榜单'
        app_label = u'api'

    name = models.CharField(verbose_name=u'榜单名称', max_length=30)
    type = models.CharField(choices=RANKBOARD_TYPE, verbose_name=u'榜单类型', max_length=8)
    image = ImgUrlField(img_type=IMG_TYPE.NOWATERMARK, verbose_name=u'主题banner', max_length=300)
    describe = models.CharField(verbose_name=u'榜单描述', max_length=200)
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    tags = models.ManyToManyField(Tag, verbose_name=u'关联标签')
    is_online = models.BooleanField(verbose_name=u'是否上线')
    share_title = models.CharField(verbose_name=u'分享标题', max_length=100)
    share_content = models.CharField(verbose_name=u'分享内容', max_length=300)
    share_image = ImgUrlField(u'分享图片', img_type=IMG_TYPE.SHARE, max_length=300)

    @classmethod
    def get_data_by_id(cls, service_id, lat=0, lng=0):
        service = Service.objects.get(pk=service_id)
        return {
            'id': service_id,
            'short_desc': service.show_name,
            'doctor': service.doctor.name,
            'hospital': service.doctor.hospital.name if service.doctor.doctor_type == DOCTOR_TYPE.DOCTOR else '',
            'image': service.image_header + '-thumb',
            'distance': display_distances(calc_distances_by_lat_lnt(lat, lng,
                                                                    service.doctor.hospital.baidu_loc_lat,
                                                                    service.doctor.hospital.baidu_loc_lng)),
            'star': service.rating,
            'tags': service.doctor.hospital.get_hospital_tags()[:3],
            'price': service.lowest_gengmei_price,
            'is_price_range': service.is_multiattribute,
            'desc': ''
        }

    def get_data_for_backend(self):
        return {
            'id': self.id,
            'title': self.name,
            'image_url': self.get_icon_url(),
            'url': '',
            'type': self.type,
            'banner': self.image,
            'desc': self.describe
        }

    def get_icon_url(self):
        return 'https://heras.igengmei.com/2018/01/18/acb8f5dbc0'

    def get_rank_type(self):
        if self.type == RANKBOARD_TYPE.DOCTOR:
            return 'expert'
        elif self.type == RANKBOARD_TYPE.SERVICE:
            return 'service'
        elif self.type == RANKBOARD_TYPE.HOSPITAL:
            return 'organization'
        else:
            return 'unknow'


class RankBoardMap(models.Model):
    class Meta:
        verbose_name = u'榜单映射'
        app_label = u'api'

    batch_rankboard = models.ForeignKey(RankBoardBatch, verbose_name=u'关联聚合榜单')
    manual_rankboard = models.ForeignKey(RankBoard, verbose_name=u'关联个性化榜单')
    city = models.ForeignKey(City, verbose_name=u'关联城市')
    is_effect = models.BooleanField(verbose_name=u'是否生效')
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)


