#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.db.models import Q

from gm_types.gaia import (
    SKIN_CONF_ACNE_TYPE,
    SKIN_CONF_CHEEK_TYPE,
    SKIN_CONF_CHIN_TYPE,
    SKIN_CONF_COLOR_TEMP_TYPE,
    SKIN_CONF_HEITOU_TYPE,
    SKIN_CONF_MAOKONG_TYPE,
    SKIN_CONF_PIGMENTAL_TYPE,
    SKIN_CONF_SMOOTH_TYPE,
    SKIN_CONF_STRUCT_TYPE,
    SKIN_CONF_T_ZONE_TYPE,
    SKIN_CONF_VASCULAR_TYPE,
    SKIN_CONF_ACT_WRINKLE_TYPE,
    SKIN_CONF_EYE_BAG_TYPE,
)

from api.models.face import (
    Acne,
    Heitou,
    HeiYanQuan,
    SkinAge,
    SkinOil,
    SkinColor,
    Smoothlevel,
    ActWrinkle,
    EyeBag,
)
from rpc.tool.dict_mixin import to_dict


class SkinBase(object):
    model = None
    base_query = Q(is_online=True)
    filter_query = Q()

    @classmethod
    def _get_info_by_query(cls, filter_query):
        result = {}

        if filter_query:
            filter_query &= cls.base_query
            obj = cls.model.objects.filter(filter_query).order_by("-id").first()
            if obj:
                result = to_dict(obj, excludes=["is_online", "created_time", "updated_time"])

        return result

    @staticmethod
    def convert_filter_query(filters, filter_params_dic):

        filter_query = Q()
        filter_query.connector = "AND"

        if all([filters.get(k) in v for k, v in filter_params_dic.items()]):
            for param in filter_params_dic:
                filter_query.children.append((param, filters[param]))

        return filter_query


class SkinAgeService(SkinBase):
    """肤龄"""
    model = SkinAge

    @classmethod
    def get_skin_age_info(cls, filters):

        if not filters:
            return {}

        skin_age = filters.get("skin_age", 0)
        # 最大，最小 均是闭区间
        filter_query = Q(min_age__lte=skin_age, max_age__gte=skin_age)
        result = cls._get_info_by_query(filter_query)

        return result


class SkinOilService(SkinBase):
    """油脂"""
    model = SkinOil

    @classmethod
    def get_skin_oil_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "t_zone": SKIN_CONF_T_ZONE_TYPE,
            "chin": SKIN_CONF_CHIN_TYPE,
            "cheek": SKIN_CONF_CHEEK_TYPE,
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class HeiTouService(SkinBase):
    """黑头毛孔"""
    model = Heitou

    @classmethod
    def get_heitou_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "heitou_level": SKIN_CONF_HEITOU_TYPE,
            "maokong_level": SKIN_CONF_MAOKONG_TYPE,
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class AcneService(SkinBase):
    """痘痘"""
    model = Acne

    @classmethod
    def get_acne_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "level": SKIN_CONF_ACNE_TYPE,
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class SmoothLevelService(SkinBase):
    """光滑度"""
    model = Smoothlevel

    @classmethod
    def get_smooth_level_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "level": SKIN_CONF_SMOOTH_TYPE,
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result

    @classmethod
    def get_smooth_all_images_info(cls):
        """
        获取所有的图片
        :return:
        """
        _all_smooth_values = set(v for v, _ in SKIN_CONF_SMOOTH_TYPE)
        smooth_list = cls.model.objects.filter(
            is_online=True).order_by("-id").values("level", "level_image")

        result = []
        _smooth_remove_set = set()
        for item in smooth_list:
            _level = item["level"]
            _image_url = item["level_image"]

            if _level not in _smooth_remove_set:
                _smooth_remove_set.add(_level)
                result.append({
                    "smooth_level_id": _level,  # 皮肤光滑度等级
                    "image_url": _image_url,  # 对应图片
                })

            # 当值全部获取后，退出
            if not _smooth_remove_set.symmetric_difference(_all_smooth_values):
                break

        return result


class HeiYanQuanService(SkinBase):
    """黑眼圈"""
    model = HeiYanQuan

    @classmethod
    def get_dark_circle_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "pigmental": SKIN_CONF_PIGMENTAL_TYPE,    # 色素
            "vascular": SKIN_CONF_VASCULAR_TYPE,     # 血管
            "struct": SKIN_CONF_STRUCT_TYPE,    # 结构
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class SkinColorService(SkinBase):
    """肤色"""
    model = SkinColor

    @classmethod
    def get_skin_color_info(cls, filters):
        result = {}

        if not filters:
            return result

        filter_params_dic = {
            "color_level": list(range(1, 9)),   # 色号
            "color_temperature": SKIN_CONF_COLOR_TEMP_TYPE,  # 色温
        }

        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class ActWrinklesService(SkinBase):
    """
    法令纹
    """
    model = ActWrinkle

    @classmethod
    def get_wrinkles_info(cls, filters):
        result = {}
        if not filters:
            return result

        filter_params_dic = {
            "state": SKIN_CONF_ACT_WRINKLE_TYPE,  # 法令纹状态
        }
        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result


class EyeBagService(SkinBase):
    """
    眼袋
    """
    model = EyeBag

    @classmethod
    def get_eye_bag_info(cls, filters):
        result = {}
        if not filters:
            return result

        filter_params_dic = {
            "state": SKIN_CONF_EYE_BAG_TYPE,  # 眼袋状态
        }
        filter_query = cls.convert_filter_query(filters, filter_params_dic)
        result = cls._get_info_by_query(filter_query)

        return result
