from rest_framework import viewsets
from utils.page import MyPageNumberPagination
from utils.datasolve import sumOfList, transportation_calculate
from utils.md5 import Md5
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

from rest_framework.response import Response
from rest_framework.exceptions import APIException
from django.utils import timezone

from .models import BoundListModel, BoundDetailModel,BoundBatchModel, BatchLogModel, OutBatchModel,OutBoundDetailModel
# from .files import FileListRenderCN, FileDetailRenderCN

from .serializers import BoundListGetSerializer,BoundListPostSerializer,BoundBatchGetSerializer,BoundBatchPostSerializer,BoundDetailGetSerializer,BoundDetailPostSerializer
from .serializers import OutBoundDetailGetSerializer,OutBoundDetailPostSerializer,OutBatchGetSerializer,OutBatchPostSerializer,BatchLogGetSerializer
from .filter import BoundListFilter, BoundDetailFilter,BoundBatchFilter
from .filter import OutBatchFilter,OutBoundDetailFilter,BatchlogFilter
# 以后添加模块检验
from warehouse.models import ListModel as warehouse
from staff.models import ListModel as staff
from rest_framework.permissions import AllowAny


class BoundListViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)
        list:
            Response a data list(all)
        create:
            Create a data line(post)

        delete:
            Delete a data line(delete)

    """
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = BoundListFilter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:
                return BoundListModel.objects.filter( is_delete=False)
            else:
                return BoundListModel.objects.filter( id=id, is_delete=False)
        else:
            return BoundListModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return BoundListGetSerializer
        elif self.action in ['create', 'update']:
            return BoundListPostSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def create(self, request, *args, **kwargs):

        data = self.request.data
        # if BoundListModel.objects.filter(code=data['code'], is_delete=False).exists():
        #     raise APIException({"detail": "Data exists"})
        # else:
        data['openid'] = self.request.auth.openid
        data['bound_date'] =str(timezone.now().strftime('%Y-%m-%d'))
        order_day=str(timezone.now().strftime('%Y-%m-'))
        data['bound_month'] =str(timezone.now().strftime('%Y%m'))
        if data['bound_type'] == 'in':
            data['bound_status'] = '100'
        else:
            data['bound_status'] = '200'
        

        qs_set = BoundListModel.objects.filter(bound_month=data['bound_month'], bound_code_type=data['bound_code_type'], is_delete=False)
        print('qs_set是:', len(qs_set))
        if len(qs_set) > 0:
            bound_last_code = qs_set.order_by('-id').first().bound_code
            data['bound_code'] = data['bound_code_type'] +'-'+ order_day + str(int(bound_last_code.split('-')[-1])+1).zfill(4)
        else:
            data['bound_code'] = data['bound_code_type'] +'-'+ order_day + '0001'

        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)
    
    def update(self, request, pk):
        qs = self.get_object()
        data = self.request.data
        serializer = self.get_serializer(qs, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)


    def destroy(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
        else:
            qs.is_delete = True
            qs.bound_code =qs.bound_code+'-delete'+str(timezone.now().strftime('%Y%m%d%H%M%S'))
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)
class BoundBatchViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)
            list:
            Response a data list(all)
            create:
            Create a data line(post)
        delete:
            Delete a data line(delete)
            """
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = BoundBatchFilter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:
                return BoundBatchModel.objects.filter( is_delete=False)
            else:
                return BoundBatchModel.objects.filter( id=id, is_delete=False)
        else:
            return BoundBatchModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return BoundBatchGetSerializer
        elif self.action in ['create', 'update']:
            return BoundBatchPostSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def create(self, request, *args, **kwargs):
        data = self.request.data
        try:
            data['openid'] = self.request.auth.openid
            data['goods_total_weight'] = data['goods_weight']*data['goods_qty']
        
            order_day=str(timezone.now().strftime('-%Y%m'))
            order_month=str(timezone.now().strftime('%Y%m'))
            data['bound_month'] =str(timezone.now().strftime('%Y%m'))
            print(data['order'])
            if data['order'] == 'true':
                qs_set = BoundBatchModel.objects.filter( goods_code=data['goods_code'], bound_month=order_month,  is_delete=False)
                print('qs_set是:', len(qs_set))
                if len(qs_set) > 0:
                    bound_last_code = qs_set.order_by('-id').first().bound_number
                    data['bound_batch_order'] = int(bound_last_code.split('-')[-1])+1
                    data['bound_number'] = data['goods_code'] + '-' + str(int(bound_last_code.split('-')[-1])+1)
                else:
                    data['bound_batch_order'] = int(order_day.split('-')[-1])*100 +1
                    data['bound_number'] = data['goods_code'] + order_day + '01'
            else:
                data['bound_number'] = data['goods_code'] + '-' + str(data['bound_batch_order'])
            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            self.add_batch_log(serializer.data, 0, data['goods_qty'])

            return Response(serializer.data, status=200, headers=headers)
        except Exception as e:
            print(e)
            raise APIException({"detail": "{}".format(e)})
    
    def add_batch_log(self, data, log_type, goods_qty):
        choices_dict = dict(BatchLogModel.BATCH_LOG_TYPE)
        log_type_name = choices_dict.get(log_type, "未知类型")
        
        try:
            # 获取 BoundBatchModel 实例
            batch_obj = BoundBatchModel.objects.get(id=data['id'])
        except BoundBatchModel.DoesNotExist:

            return False

        log_data = {
            'batch_id': batch_obj,  
            'log_type': log_type,
            'log_date': timezone.now().strftime('%Y-%m-%d-%H:%M'),  # 直接格式化时间,无需转字符串
            'goods_code': data['goods_code'],
            'goods_desc': data['goods_desc'],
            'goods_qty': data['goods_qty'],
            'log_content': f"{log_type_name} {data['goods_qty']}件",
            'creater': data['creater'],
            'openid': data['openid'],
            'is_delete': False,
            
        }
        
        # 创建日志记录
        BatchLogModel.objects.create(**log_data)
        return True


    def update(self, request, pk):
        qs = self.get_object()
        data = self.request.data
        serializer = self.get_serializer(qs, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)

    def destroy(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
        else:
            qs.is_delete = True
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)
      
class BoundDetailViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)
            list:
            Response a data list(all)
        create:
            Create a data line(post)
        delete:
            Delete a data line(delete)
            """
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = BoundDetailFilter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None
            
    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:
                return BoundDetailModel.objects.filter( is_delete=False)
            else:
                return BoundDetailModel.objects.filter( id=id, is_delete=False)
        else:
            return BoundDetailModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return BoundDetailGetSerializer
        elif self.action in ['create', 'update']:
            return BoundDetailPostSerializer
        else:
            return self.http_method_not_allowed(request=self.request)


    def create(self, request, *args, **kwargs):
        data = self.request.data
        data['openid'] = self.request.auth.openid
        data.setdefault('is_delete', False)


        # 验证并保存数据
        data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
        print(data['detail_code'])
        if BoundDetailModel.objects.filter(detail_code=data['detail_code'], is_delete=False).exists():
            raise APIException({"detail": "Data exists"})
        else:
            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            # 返回响应
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)
    
    def update(self, request, pk):
        qs = self.get_object()
        data = self.request.data
        serializer = self.get_serializer(qs, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)

    def destroy(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
        else:
            qs.is_delete = True
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

class OutBoundDetailViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)
            list: Response a data list(all)
        create:
            Create a data line(post)
        delete:
            Delete a data line(delete)
    """
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = OutBoundDetailFilter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None            

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:            
            if id is None:
                return OutBoundDetailModel.objects.filter( is_delete=False)
            else:
                return OutBoundDetailModel.objects.filter( id=id, is_delete=False)
        else:
            return OutBoundDetailModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return OutBoundDetailGetSerializer
        elif self.action in ['create', 'update']:
            return OutBoundDetailPostSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def create(self, request, *args, **kwargs):
        data = self.request.data
        data['openid'] = self.request.auth.openid
        data.setdefault('is_delete', False)

        data['bound_batch_number'] = OutBatchModel.objects.get(id=data['bound_batch']).batch_number.id
        # 验证并保存数据
        data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
        print(data['detail_code'])
        if OutBoundDetailModel.objects.filter(detail_code=data['detail_code'], is_delete=False).exists():
            raise APIException({"detail": "Data exists"})
        else:
            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            # 返回响应
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

    def update(self, request, pk):
        qs = self.get_object()
        data = self.request.data
        serializer = self.get_serializer(qs, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)

    def destroy(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:
            raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
        else:
            qs.is_delete = True
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)       

class OutBoundBatchViewSet(viewsets.ModelViewSet):
    """
        retrieve:
            Response a data list(get)
            list:
            Response a data list(all)
            create:
            Create a data line(post)
        delete:
            Delete a data line(delete)
            """
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = OutBatchFilter

    def get_project(self):
        try:
            id = self.kwargs.get('pk')
            return id
        except:
            return None

    def get_queryset(self):
        id = self.get_project()
        if self.request.user:
            if id is None:                
                return OutBatchModel.objects.filter( is_delete=False)
            else:
                return OutBatchModel.objects.filter( id=id, is_delete=False)
        else:
            return OutBatchModel.objects.none()

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return OutBatchGetSerializer
        elif self.action in ['create', 'update']:
            return OutBatchPostSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def create(self, request, *args, **kwargs):
        data = self.request.data
        batch_obj = BoundBatchModel.objects.get(bound_number=data['out_number'])
        if batch_obj is None:
            raise APIException({"detail": "批次不存在"})

        data['batch_number'] = batch_obj.id
        data['out_date'] = str(timezone.now().strftime('%Y-%m-%d %H:%M:%S'))

        data['openid'] = self.request.auth.openid
        data.setdefault('is_delete', False)
        data['goods_total_weight'] = data['goods_weight']*data['goods_out_qty']
        data['goods_qty'] = batch_obj.goods_qty -batch_obj.goods_out_qty - data['goods_out_qty']
        batch_obj.goods_out_qty += data['goods_out_qty']
        
        if batch_obj.goods_out_qty > batch_obj.goods_in_qty:
            raise APIException({"detail": "出库数量大于批次数量"})
        batch_obj.goods_qty -= data['goods_out_qty']
        batch_obj.save()
        data['status'] = 0  #现在处于出库申请状态
   
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        self.add_batch_log(serializer.data, 1, data['goods_out_qty'])
        
        return Response(serializer.data, status=200, headers=headers)

    def update(self, request, pk):        
        qs = self.get_object()
        data = self.request.data
        data['openid'] = self.request.auth.openid
        data.setdefault('is_delete', False)
        data['goods_total_weight'] = data['goods_weight']*data['goods_qty']
        serializer = self.get_serializer(qs, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        headers = self.get_success_headers(serializer.data)
        self.add_batch_log(serializer.data, 1, data['goods_qty'])
        return Response(serializer.data, status=200, headers=headers)

    def destroy(self, request, pk):
        qs = self.get_object()
        if qs.openid != self.request.auth.openid:            
            raise APIException({"detail": "该出库非您所属,禁止删除,您可以进行编辑"})
        else:
            qs.is_delete = True
            qs.save()
            serializer = self.get_serializer(qs, many=False)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=200, headers=headers)

    def add_batch_log(self, data, log_type, goods_qty):
        choices_dict = dict(BatchLogModel.BATCH_LOG_TYPE)
        log_type_name = choices_dict.get(log_type, "未知类型")

        try:
            # 获取 BoundBatchModel 实例
            batch_obj = BoundBatchModel.objects.get(id=data['batch_number'])
        except BoundBatchModel.DoesNotExist:
            # 处理批次不存在的情况(如记录日志或抛出异常)
            return False

        log_data = {            
            'batch_id': batch_obj,  # 关键修复:传入实例对象,而不是 batch_obj.id
            'log_type': log_type,
            'log_date': timezone.now().strftime('%Y-%m-%d-%H:%M'),  # 直接格式化时间,无需转字符串
            'goods_code': data['goods_code'],
            'goods_desc': data['goods_desc'],
            'goods_qty': data['goods_qty'],
            'log_content': f"{log_type_name} {goods_qty}件",
            'creater': data['creater'],
            'openid': data['openid'],
            'is_delete': False,
            # 注意:create_time 和 update_time 由模型的 auto_now_add 和 auto_now 自动处理,无需手动赋值
        }

        # 创建日志记录
        BatchLogModel.objects.create(**log_data)
        return True 
class BoundBatchLogViewSet(viewsets.ModelViewSet):
    
    """
        retrieve:
            Response a data list(get)
            list:
            Response a data list(all)
     
            delete:
            Delete a data line(delete)
    """ 
    # authentication_classes = []  # 禁用所有认证类
    # permission_classes = [AllowAny]  # 允许任意访问
    pagination_class = MyPageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
    ordering_fields = ['id', "create_time", "update_time", ]
    filter_class = BatchlogFilter

    def get_queryset(self):

        return BatchLogModel.objects.filter( is_delete=False)
        

    def get_serializer_class(self):
        if self.action in ['list', 'destroy','retrieve']:
            return BatchLogGetSerializer
        else:
            return self.http_method_not_allowed(request=self.request)

    def destroy(self, request, pk):
        qs = self.get_object()
        qs.is_delete = True
        qs.save()
        serializer = self.get_serializer(qs, many=False)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=200, headers=headers)