#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, print_function

import datetime

from django.db.models import Q, F

from mark.models import (
    MarkActivity,
    MarkActivityTag,
    MarkFortuneConfigs,
    UserMarkLog,
    UserMarkLogStatistic,
)


class ServiceBase(object):

    @staticmethod
    def get_objs_by_query_and_order(model_set, query, order_by=[]):
        """
        获取 query_set对象
        :param model_set:
        :param query:
        :param order_by:
        :return:
        """
        _queryset = model_set.objects.filter(
            query).order_by(*order_by)

        return _queryset


class MarkActivityService(ServiceBase):
    """
    活动
    """
    @classmethod
    def get_mark_activity_obj_by_id(cls, mark_activity_id):
        return cls.get_objs_by_query_and_order(
            model_set=MarkActivity,
            query=Q(is_online=True, pk=mark_activity_id)
        ).first()

    @classmethod
    def get_mark_activity_rel_tags(cls, mark_activity_id):
        """
        获取活动关联标签
        :param mark_activity_id:
        :return:
        """
        _rel_tags = cls.get_objs_by_query_and_order(
            model_set=MarkActivityTag,
            query=Q(mark_activity_id=mark_activity_id)
        ).values_list("tag_id", flat=True)

        return list(_rel_tags)

    @classmethod
    def get_mark_fortune_config(cls, query):
        """
        获取运势
        :param mark_activity_id:
        :param skin_trait_id:
        :param constellation:
        :return:
        """
        mark_fortune_obj = cls.get_objs_by_query_and_order(
            model_set=MarkFortuneConfigs,
            query=query
        ).first()

        return mark_fortune_obj


class UserMarkLogService(ServiceBase):
    """
    用户打卡日志
    """

    @classmethod
    def get_user_today_mark_counts(cls, user_id, mark_activity_id):
        """
        获取用户今日的打卡次数
        :param user_id:
        :param mark_activity_id:
        :return:
        """

        if not all([user_id, mark_activity_id]):
            return 0

        query = Q(
            user_id=user_id,
            mark_activity_id=mark_activity_id,
            mark_date=datetime.date.today()
        )

        statistic_obj = cls.get_objs_by_query_and_order(
            model_set=UserMarkLogStatistic,
            query=query
        ).first()

        return getattr(statistic_obj, "daily_check_nums", 0)

    @classmethod
    def update_user_mark_log_params(cls, filters, updates):
        """
        更新用户打卡记录表某些数据
        :param filters:
        :param updates:
        :return:
        """
        update_status = False

        user_mark_log_obj = UserMarkLog.objects.filter(**filters).first()
        if not user_mark_log_obj:
            return update_status

        if getattr(user_mark_log_obj, 'mark_fortune_id', 0) != updates["mark_fortune_id"]:
            for k, v in updates.items():
                setattr(user_mark_log_obj, k, v)

            user_mark_log_obj.save(update_fields=list(updates.keys()))
            update_status = True

        return update_status

    @classmethod
    def create(cls, user_id, device_id, mark_activity_id, skin_result_id, skin_data_source, mark_fortune_id=0):
        """
        此处得保证数据的唯一性和有效性
        :param user_id:
        :param device_id:
        :param mark_activity_id:
        :param skin_result_id:
        :param skin_data_source:
        :param mark_fortune_id:
        :return:
        """
        user_mark_log_create_params = {
            "user_id": user_id,
            "mark_activity_id": mark_activity_id,
            "mark_fortune_id": mark_fortune_id,
            "skin_result_id": skin_result_id,
            "skin_data_source": skin_data_source,
        }

        user_mark_log_obj, user_mark_log_status = UserMarkLog.objects.get_or_create(
            defaults={
                "device_id": device_id,
                "mark_date": datetime.date.today(),
            },
            **user_mark_log_create_params
        )
        if user_mark_log_status:  # 只有log数据创建成功，才会去更新统计表数据

            statistic_obj, _ = UserMarkLogStatistic.objects.get_or_create(
                defaults={
                    "device_id": device_id,
                },
                **{
                    "user_id": user_id,
                    "mark_activity_id": mark_activity_id,
                    "mark_date": datetime.date.today(),
                }
            )
            statistic_obj.daily_check_nums = F("daily_check_nums") + 1
            statistic_obj.save(update_fields=["daily_check_nums"])

        return user_mark_log_obj
