from django_filters import rest_framework as filters
from apps.wpm.models import (SfLog, StLog, WMaterial, Mlog, 
                             Handover, Mgroup, Mlogb, Mtask, BatchSt)
from apps.mtm.models import Route
from django.db.models import Q
from rest_framework.exceptions import ParseError

class SfLogFilter(filters.FilterSet):
    class Meta:
        model = SfLog
        fields = {
            "mgroup": ["exact"],
            "shift": ["exact"],
            "team": ["exact"],
            "leader": ["exact"],
            "team__belong_dept": ["exact"],
            "end_time": ["day", "month", "year", "lt"],
            "start_time": ["gte"]
        }


class StLogFilter(filters.FilterSet):
    class Meta:
        model = StLog
        fields = {
            "mgroup": ["exact"],
            "mgroup__name": ["exact"],
            "start_time": ["day", "month", "year", "gte", "lte"],
            "sflogs__team": ["exact"],
            "end_time": ["isnull"],
            "sflog": ["exact"],
            "sflogs": ["exact"],
            "cate": ["exact"],
        }


class WMaterialFilter(filters.FilterSet):
    mgroupx = filters.CharFilter(label='MgroupId', method='filter_mgroupx')
    mtaskx = filters.CharFilter(label='MtaskId', method='filter_mtaskx')
    route = filters.CharFilter(label='routeId', method='filter_route')

    def filter_mgroupx(self, queryset, name, value):
        return queryset.filter(mgroup__id=value)|queryset.filter(belong_dept=Mgroup.objects.get(id=value).belong_dept, mgroup=None)
    
    def filter_mtaskx(self, queryset, name, value):
        mtask = Mtask.objects.get(id=value)
        if mtask.route and mtask.route.batch_bind:
            return WMaterial.mat_in_qs(mtask=Mtask.objects.get(id=value), qs=queryset)
        return queryset

    def filter_route(self, queryset, name, value):
        try:
            route = Route.objects.get(id=value)
        except Route.DoesNotExist:
            raise ParseError('生产路线不存在!')
        return queryset.filter(material=route.material_in)|queryset.filter(material__in=route.materials.all())
    
    class Meta:
        model = WMaterial
        fields = {
            "material": ["exact", "in"],
            "state": ["exact", "in"],
            "material__type": ["exact", "in"],
            "material__name": ["exact", "in", "contains"],
            "material__process": ["exact", "in"],
            "material__process__name": ["exact", "contains", "in"],
            "belong_dept": ["exact"],
            "belong_dept__name": ["exact", "in"],
            "batch": ["exact", "contains"],
            "mgroup": ["exact", "in", "isnull"],
            "mgroup__name": ["exact", "in"],
            "count": ["gte", "lte", "exact"],
            "notok_sign": ["exact", "in", "isnull"],
            "count_xtest": ["gte", "isnull"],
            "supplier": ["exact"],
        }

class MlogFilter(filters.FilterSet):
    class Meta:
        model = Mlog
        fields = {
            "mtask": ["exact", "in"],
            "batch": ["exact"],
            "handle_date": ["exact"],
            "handle_user": ["exact"],
            "mgroup": ["exact"],
            "mtask__mgroup__belong_dept__name": ["exact", "contains", "in"],
            "mgroup__belong_dept__name": ["exact", "in", "contains"],
            "mgroup__name": ["exact", "in", "contains"],
            "submit_time": ["isnull"],
            "fmlog": ["exact"]
        }


class HandoverFilter(filters.FilterSet):
    mgroup = filters.CharFilter(label='MgroupId', method='filter_mgroup')
    dept = filters.CharFilter(label='DeptId', method='filter_dept')

    def filter_mgroup(self, queryset, name, value):
        return queryset.filter(send_mgroup__id=value)|queryset.filter(recive_mgroup__id=value)
    
    def filter_dept(self, queryset, name, value):
        return queryset.filter(send_dept__id=value)|queryset.filter(recive_dept__id=value)

    class Meta:
        model = Handover
        fields = {
            "id": ["exact"],
            "batch": ["exact", "contains"],
            "material": ["exact", "in"],
            "send_user": ["exact"],
            "send_dept": ["exact"],
            "send_dept__name": ["exact"],
            "recive_dept": ["exact"],
            "recive_dept__name": ["exact"],
            "send_date": ["exact"],
            "material__type": ["exact", "in"],
            "material__process": ["exact", "in"],
            "material__process__name": ["exact", "contains", "in"],
            "submit_time": ["isnull"],
            "mlog": ["isnull"],
            "send_mgroup": ["exact"],
            "send_mgroup__name": ["exact"],
            "recive_mgroup": ["exact"],
            "recive_mgroup__name": ["exact"],
            "type": ["exact", "in"],
        }


class MlogbFilter(filters.FilterSet):
    type = filters.CharFilter(label="in/out", method='filter_type')
    class Meta:
        model = Mlogb
        fields = {
            "mlog": ["exact"],
            "mtask": ["exact"],
            "wm_in": ["exact"],
            "mlog__submit_time": ["isnull"],
            "wm_in__state": ["exact"],
            "material_in": ["exact", "isnull"],
            "material_out": ["exact", "isnull"],
        }
    
    def filter_type(self, queryset, name, value):
        if value:
            if value == 'in':
                return queryset.filter(material_in__isnull=False)
            elif value == 'out':
                return queryset.filter(material_out__isnull=False)
            return queryset
        return queryset.none()
    

class BatchStFilter(filters.FilterSet):
    batch__startswith__in = filters.CharFilter(method='filter_batch')

    class Meta:
        model = BatchSt
        fields = {
            "batch": ["exact", "contains", "startswith"],
            "last_time": ["exact", "gte", "lte"],
            "update_time": ["exact", "gte", "lte"]
        }

    def filter_batch(self, queryset, name, value):
        v_list = value.split(',')
        query = Q()
        for value in v_list:
            query |= Q(batch__startswith=value)
        return queryset.filter(query)