# -*- coding: UTF-8 -*-
from django.db import IntegrityError
from django.db.models import Q
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery

from api.models import Country, Province, City, Area, Region, CityScale, CityScaleNeabyCity
from gm_dataquery.db import DB

from rpc.exceptions import UniError


class CityDB(DataBuilder):
    def getval_province__name(self, obj):
        return obj.province.name if getattr(obj, 'province', None) else ''

    def getval_has_hospital(self, obj):
        return obj.is_hospital_exists()


@DB
class CityDQ(DataSQLQuery):
    model = City
    data_model = CityDB
    pass


class ProvinceDB(DataBuilder):
    pass


@DB
class ProvinceDQ(DataSQLQuery):
    model = Province
    data_model = ProvinceDB
    pass


class CountryDB(DataBuilder):
    pass


@DB
class CountryDQ(DataSQLQuery):
    model = Country
    data_model = CountryDB
    pass


class RegionDB(DataBuilder):
    pass


@DB
class RegionDQ(DataSQLQuery):
    model = Region
    data_model = RegionDB


class CityScaleDB(DataBuilder):
    def getval_nearby_cities(self, obj):
        return list(obj.nearby_cities.values_list("nearby_city_id", flat=True))


@DB
class CityScaleDQ(DataSQLQuery):
    model = CityScale
    data_model = CityScaleDB

    def create(self, **kwargs):
        try:
            nearby_cities = kwargs.pop("nearby_cities", [])
            obj_dict = super(CityScaleDQ.sqlquery, self).create(**kwargs)
            city_list = [
                CityScaleNeabyCity(cityscale_id=obj_dict['id'], nearby_city_id=city_id)
                for city_id in nearby_cities]
            CityScaleNeabyCity.objects.bulk_create(city_list)
            return obj_dict

        except IntegrityError:
            raise UniError("该城市已配置，不能新建")

    def update(self, updates, **kwargs):
        is_delete = updates.pop('is_delete', False)
        if is_delete:
            qs = CityScale.objects.filter(**kwargs)
            CityScaleNeabyCity.objects.filter(cityscale__in=qs).delete()
            count = qs.count()
            qs.delete()
            return count

        if "nearby_cities" in updates:
            new_nearby_city_ids = set(updates.pop("nearby_cities", []))
            has_nearby_city_ids = set(CityScaleNeabyCity.objects.filter(
                cityscale_id=kwargs["id"]).values_list("nearby_city_id", flat=True))

            for city_id in new_nearby_city_ids - has_nearby_city_ids:
                CityScaleNeabyCity.objects.get_or_create(cityscale_id=kwargs["id"], nearby_city_id=city_id)

            CityScaleNeabyCity.objects.filter(
                cityscale_id=kwargs["id"], nearby_city_id__in=(has_nearby_city_ids - new_nearby_city_ids)).delete()

        return super(CityScaleDQ.sqlquery, self).update(updates, **kwargs)
