from django_filters import rest_framework as filters
from apps.enm.models import MpointStat, EnStat, EnStat2
from datetime import datetime
from django.db.models import F, Q
from rest_framework.exceptions import ParseError


class MpointStatFilter(filters.FilterSet):
    has_create_by = filters.BooleanFilter(method="filter_has_create_by")
    start_time = filters.CharFilter(method="filter_start_time")
    end_time = filters.CharFilter(method="filter_end_time")

    class Meta:
        model = MpointStat
        fields = {
            "mpoint": ["exact", "in"],
            "mgroup": ["exact"],
            "mgroup__name": ["exact"],
            "mpoint__mgroup": ["exact"],
            "mpoint__material": ["exact"],
            "mpoint__code": ["exact"],
            "mpoint__material__code": ["exact", "in", 'contains'],
            "mpoint__need_display": ["exact"],
            "mpoint__mgroup__belong_dept": ["exact"],
            "mpoint__ep_belong": ["exact"],
            "mpoint__ep_monitored": ["exact", "isnull"],
            "mpoint__ep_monitored__power_kw": ["exact", "gte"],
            "sflog": ["exact"],
            "hour": ["exact"],
            "day": ["exact"],
            "month": ["exact"],
            "year": ["exact"],
            "day_s": ["exact"],
            "month_s": ["exact"],
            "year_s": ["exact"],
            "create_by": ["exact"],
            "type": ["exact"],
            "mpoint__type": ["exact"],
            "val_level": ["exact"]
        }

    def filter_has_create_by(self, queryset, name, value):
        if value:
            queryset = queryset.exclude(create_by=None)
        else:
            queryset = queryset.filter(create_by=None)
        return queryset

    def filter_start_time(self, queryset, name, value):
        query = self.data
        if "type" not in query:
            raise ParseError("type参数缺失")
        start_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        start_year, start_month, start_day, start_hour = start_time.year, start_time.month, start_time.day, start_time.hour
        if query["type"] in ["hour_s", "hour"]:
            queryset = queryset.filter(
                Q(year__gt=start_year)
                | Q(year=start_year, month__gt=start_month)
                | Q(year=start_year, month=start_month, day__gt=start_day)
                | Q(year=start_year, month=start_month, day=start_day, hour__gte=start_hour)
            )
        elif query["type"] in ["sflog", "day_s"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gt=start_month) | Q(year_s=start_year, month_s=start_month, day_s__gte=start_day))
        elif query["type"] in ["month_s", "month_st"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gte=start_month))
        elif query["type"] in ["year_s"]:
            queryset = queryset.filter(Q(year_s__gte=start_year))
        elif query["type"] in ["day"]:
            queryset = queryset.filter(Q(year__gt=start_year) | Q(year=start_year, month__gt=start_month) | Q(year=start_year, month=start_month, day__gte=start_day))
        elif query["type"] in ["month"]:
            queryset = queryset.filter(Q(year__gt=start_year) | Q(year=start_year, month__gte=start_month))
        elif query["type"] in ["year"]:
            queryset = queryset.filter(Q(year__gte=start_year))
        return queryset

    def filter_end_time(self, queryset, name, value):
        query = self.data
        if "type" not in query:
            raise ParseError("type参数缺失")
        end_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        end_year, end_month, end_day, end_hour = end_time.year, end_time.month, end_time.day, end_time.hour
        if query["type"] in ["hour_s", "hour"]:
            queryset = queryset.filter(
                Q(year__lt=end_year)
                | Q(year=end_year, month__lt=end_month)
                | Q(year=end_year, month=end_month, day__lt=end_day)
                | Q(year=end_year, month=end_month, day=end_day, hour__lt=end_hour)
            )
        elif query["type"] in ["sflog", "day_s"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lt=end_month) | Q(year_s=end_year, month_s=end_month, day_s__lte=end_day))
        elif query["type"] in ["month_s", "month_st"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lte=end_month))
        elif query["type"] in ["year_s"]:
            queryset = queryset.filter(Q(year_s__lte=end_year))
        elif query["type"] in ["day"]:
            queryset = queryset.filter(Q(year__lt=end_year) | Q(year=end_year, month__lt=end_month) | Q(year=end_year, month=end_month, day__lte=end_day))
        elif query["type"] in ["month"]:
            queryset = queryset.filter(Q(year__lt=end_year) | Q(year=end_year, month__lte=end_month))
        elif query["type"] in ["year"]:
            queryset = queryset.filter(Q(year__lte=end_year))
        return queryset


class EnStatFilter(filters.FilterSet):
    start_time = filters.CharFilter(method="filter_start_time")
    end_time = filters.CharFilter(method="filter_end_time")

    class Meta:
        model = EnStat
        fields = {
            "mgroup": ["exact"],
            "mgroup__name": ["exact"],
            "mgroup__belong_dept": ["exact"],
            "type": ["exact"],
            "sflog": ["exact"],
            "team": ["exact"],
            "day_s": ["exact"],
            "month_s": ["exact"],
            "year_s": ["exact"],
            "year": ["exact"],
            "month": ["exact"],
            "day": ["exact"],
            "hour": ["exact"],
        }

    def filter_start_time(self, queryset, name, value):
        query = self.data
        start_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        start_year, start_month, start_day, start_hour = start_time.year, start_time.month, start_time.day, start_time.hour
        if query["type"] in ["hour_s"]:
            queryset = queryset.filter(
                Q(year_s__gt=start_year)
                | Q(year_s=start_year, month_s__gt=start_month)
                | Q(year_s=start_year, month_s=start_month, day_s__gt=start_day)
                | Q(year_s=start_year, month_s=start_month, day_s=start_day, hour__gte=start_hour)
            )
        elif query["type"] in ["sflog", "day_s"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gt=start_month) | Q(year_s=start_year, month_s=start_month, day_s__gte=start_day))
        elif query["type"] in ["month_s", "month_st"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gte=start_month))
        elif query["type"] in ["year_s"]:
            queryset = queryset.filter(Q(year_s__gte=start_year))
        return queryset

    def filter_end_time(self, queryset, name, value):
        query = self.data
        end_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        end_year, end_month, end_day, end_hour = end_time.year, end_time.month, end_time.day, end_time.hour
        if query["type"] in ["hour_s"]:
            queryset = queryset.filter(
                Q(year_s__lt=end_year)
                | Q(year_s=end_year, month_s__lt=end_month)
                | Q(year_s=end_year, month_s=end_month, day_s__lt=end_day)
                | Q(year_s=end_year, month_s=end_month, day_s=end_day, hour__lte=end_hour)
            )
        elif query["type"] in ["sflog", "day_s"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lt=end_month) | Q(year_s=end_year, month_s=end_month, day_s__lte=end_day))
        elif query["type"] in ["month_s", "month_st"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lte=end_month))
        elif query["type"] in ["year_s"]:
            queryset = queryset.filter(Q(year_s__lte=end_year))
        return queryset


class EnStat2Filter(filters.FilterSet):
    start_time = filters.CharFilter(method="filter_start_time")
    end_time = filters.CharFilter(method="filter_end_time")

    class Meta:
        model = EnStat2
        fields = {
            "type": ["exact"],
            "day_s": ["exact"],
            "month_s": ["exact"],
            "year_s": ["exact"],
        }

    def filter_start_time(self, queryset, name, value):
        query = self.data
        start_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        start_year, start_month, start_day, start_hour = start_time.year, start_time.month, start_time.day, start_time.hour
        if query["type"] in ["day_s"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gt=start_month) | Q(year_s=start_year, month_s=start_month, day_s__gte=start_day))
        elif query["type"] in ["month_s"]:
            queryset = queryset.filter(Q(year_s__gt=start_year) | Q(year_s=start_year, month_s__gte=start_month))
        return queryset

    def filter_end_time(self, queryset, name, value):
        query = self.data
        end_time = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
        end_year, end_month, end_day, end_hour = end_time.year, end_time.month, end_time.day, end_time.hour
        if query["type"] in ["day_s"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lt=end_month) | Q(year_s=end_year, month_s=end_month, day_s__lte=end_day))
        elif query["type"] in ["month_s"]:
            queryset = queryset.filter(Q(year_s__lt=end_year) | Q(year_s=end_year, month_s__lte=end_month))
        return queryset
