from .models import (Mroom, MroomBooking, MroomSlot,  LendingSeal, VehicleUse, FileRecord, BorrowRecord, Publicity, VehicleReg, VehicleSlot)
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from django.db import transaction
from rest_framework.exceptions import ParseError
from apps.utils.constants import EXCLUDE_FIELDS
from apps.wf.serializers import TicketSimpleSerializer


class MroomSerializer(CustomModelSerializer):
    class Meta:
        model = Mroom
        fields = '__all__'


class MroomBookingSerializer(CustomModelSerializer):
    mroom = serializers.PrimaryKeyRelatedField(queryset=Mroom.objects.all(), write_only=True, label="会议室")
    mdate = serializers.DateField(write_only=True, label="预订日期")
    slots = serializers.ListField(child=serializers.IntegerField(), write_only=True, label="时段索引")
    create_by_name = serializers.CharField(source='create_by.username', read_only=True)
    create_by_phone = serializers.CharField(source='create_by.phone', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = MroomBooking
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS
        extra_kwargs = {'belong_dept': {'required': True}}
    
    def create(self, validated_data):
        mroom = validated_data.pop('mroom')
        slots = validated_data.pop('slots')
        mdate = validated_data.pop('mdate')
        booking = super().create(validated_data)
        MroomSlot.objects.filter(booking=booking).delete()
        if slots:
            for slot in slots:
                if slot < 0 or slot > 47:
                    raise ParseError("时段索引超出范围")
                ms_exists = MroomSlot.objects.filter(mroom=mroom, mdate=mdate, slot=slot, is_inuse=True).exists()
                if ms_exists:
                    raise ParseError("时段已预订,请刷新重选")
                MroomSlot.objects.create(booking=booking, slot=slot, mdate=mdate, mroom=mroom, is_inuse=True)
            return booking
        else:
            raise ParseError("请选择时段")

    def update(self, instance, validated_data):
        mroom = validated_data.pop('mroom')
        slots = validated_data.pop('slots')
        mdate = validated_data.pop('mdate')
        booking = super().update(instance, validated_data)
        MroomSlot.objects.filter(booking=instance).delete()
        if slots:
            for slot in slots:
                if slot < 0 or slot > 47:
                    raise ParseError("时段索引超出范围")
                ms_exists = MroomSlot.objects.filter(mroom=mroom, mdate=mdate, slot=slot, is_inuse=True).exists()
                if ms_exists:
                    raise ParseError("时段已预订,请刷新重选")
                MroomSlot.objects.create(booking=booking, slot=slot, mdate=mdate, mroom=mroom, is_inuse=True)
            return booking
        else:
            raise ParseError("请选择时段")
class MroomSlotSerializer(CustomModelSerializer):
    booking_title = serializers.CharField(source='booking.title', read_only=True)
    class Meta:
        model = MroomSlot
        fields = '__all__'


class VehicleRecordSerializer(CustomModelSerializer):
    class Meta:
        model = VehicleReg
        fields = '__all__'


class VehicleUseSerializer(CustomModelSerializer):
    vehreg = serializers.PrimaryKeyRelatedField(queryset=VehicleReg.objects.all(), write_only=True, label="车辆信息")
    vdate = serializers.DateField(write_only=True, label="预订日期")
    slots = serializers.ListField(child=serializers.IntegerField(), write_only=True, label="时段索引")
    create_by_name = serializers.CharField(source='create_by.username', read_only=True)
    create_by_phone = serializers.CharField(source='create_by.phone', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = VehicleUse
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS + ['actual_km']
        extra_kwargs = {'belong_dept': {'required': True}}
    
    def create(self, validated_data):
        vehreg = validated_data.pop('vehreg')
        slots = validated_data.pop('slots')
        vdate = validated_data.pop('vdate')
        validated_data['start_km'] = vehreg.km
        if validated_data.get('end_km', None):
            vehreg.km= validated_data['end_km']
        vehicle_use = super().create(validated_data)
        VehicleSlot.objects.filter(vehicle_use=vehicle_use).delete()
        if slots:
            for slot in slots:
                if slot < 0 or slot > 47:
                    raise ParseError("时段索引超出范围")
                ms_exists = VehicleSlot.objects.filter(vehreg=vehreg, vdate=vdate, slot=slot, is_inuse=True).exists()
                if ms_exists:
                    raise ParseError("时段已预订,请刷新重选")
                VehicleSlot.objects.create(vehicle_use=vehicle_use, slot=slot, vdate=vdate, vehreg=vehreg, is_inuse=True)
            return vehicle_use
        else:
            raise ParseError("请选择时段")

    def update(self, instance, validated_data):
        vehreg = validated_data.pop('vehreg')
        slots = validated_data.pop('slots')
        vdate = validated_data.pop('vdate')
        vehicle_use = super().update(instance, validated_data)
        VehicleSlot.objects.filter(vehicle_use=vehicle_use).delete()
        if slots:
            for slot in slots:
                if slot < 0 or slot > 47:
                    raise ParseError("时段索引超出范围")
                ms_exists = VehicleSlot.objects.filter(vehreg=vehreg, vdate=vdate, slot=slot, is_inuse=True).exists()
                if ms_exists:
                    raise ParseError("时段已预订,请刷新重选")
                VehicleSlot.objects.create(vehicle_use=vehicle_use, slot=slot, vdate=vdate, vehreg=vehreg, is_inuse=True)
            return vehicle_use
        else:
            raise ParseError("请选择时段")
        

class VehSlotSerializer(CustomModelSerializer):
    veh_name = serializers.CharField(source='vehreg.name', read_only=True)
    class Meta:
        model = VehicleSlot
        fields = '__all__'

class LendingSealSerializer(CustomModelSerializer):
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = LendingSeal
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS

class FileRecordSerializer(CustomModelSerializer):
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = FileRecord
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS


class BorrowRecordSerializer(CustomModelSerializer):
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    borrow_file_ = FileRecordSerializer(source='borrow_file', many=True, read_only=True, label="借阅文件详情")
    file_name = serializers.SerializerMethodField()
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = BorrowRecord
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS 

    def get_file_name(self, obj):
        return [file.name for file in obj.borrow_file.all()]


class PublicitySerializer(CustomModelSerializer):
    create_by_name = serializers.CharField(source='create_by.name', read_only=True)
    belong_dept_name = serializers.CharField(source='belong_dept.name', read_only=True)
    ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
    class Meta:
        model = Publicity
        fields = '__all__'
        read_only_fields = EXCLUDE_FIELDS




        