import json
from apps.dpm.models import CheckTaskSet, CheckWork, RiskPoint, Risk, Hazard
from rest_framework import serializers
from apps.utils.serializers import CustomModelSerializer
from apps.utils.constants import EXCLUDE_FIELDS
from apps.system.models import Dictionary
from django_celery_beat.models import PeriodicTask
import time
from django.db import transaction


class RiskPointCreateUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = RiskPoint
        exclude = EXCLUDE_FIELDS


class RiskPointSerializer(CustomModelSerializer):
    area_name = serializers.CharField(source='area.name', read_only=True)
    dept_res_name = serializers.CharField(source='dept_res.name', read_only=True)
    user_res_name = serializers.CharField(source='user_res.name', read_only=True)
    class Meta:
        model = RiskPoint
        fields = '__all__'


class RiskCreateUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = Risk
        exclude = EXCLUDE_FIELDS + ['riskd']

    def save(self, **kwargs):
        obj = super().save(**kwargs)
        if obj.riskl and obj.riske and obj.riskc:
            obj.riskd = obj.riskl * obj.riske * obj.riskc
            if obj.riskd >= 320:
                obj.level = 40
            elif 320 > obj.riskd >= 160:
                obj.level = 30
            elif 160 > obj.riskd >= 70:
                obj.level = 20
            else:
                obj.level = 10
            obj.save()
            self.cal_riskpoint_level(obj)
        return obj

    @staticmethod
    def cal_riskpoint_level(risk):
        """
        计算风险点风险等级
        """
        riskpoint = risk.riskpoint
        levels = Risk.objects.filter(riskpoint=riskpoint).values_list('level', flat=True)
        riskpoint.level = max(levels)
        riskpoint.save()
        RiskCreateUpdateSerializer.cal_area_level(riskpoint)

    @staticmethod
    def cal_area_level(riskpoint):
        """
        计算区域风险等级
        """
        area = riskpoint.area
        if area:
            levels = RiskPoint.objects.filter(area=area).values_list('level', flat=True)
            area.level = max(levels)
            area.save()


class RiskSerializer(CustomModelSerializer):
    class Meta:
        model = Risk
        fields = '__all__'


class CheckTaskSetCreateSerializer(CustomModelSerializer):
    class Meta:
        model = CheckTaskSet
        exclude = EXCLUDE_FIELDS + ['periodictask']

    def create(self, validated_data):
        with transaction.atomic():
            sch = validated_data["myschedule"]
            pobj = PeriodicTask()
            pobj.name = 'checktask_' + time.strftime('%Y%m%d%H%M%S')
            pobj.task = 'apps.dpm.tasks.dispath_checkwork_task'
            if sch.crontab:
                pobj.crontab = sch.crontab
            elif sch.interval:
                pobj.interval = sch.interval
            pobj.save()
            validated_data["periodictask"] = pobj
            ins = super().create(validated_data)
            pobj.kwargs = json.dumps({'checktaskset': ins.id})
            pobj.save()
            return ins

class CheckTaskSetUpdateSerializer(CustomModelSerializer):
    class Meta:
        model = CheckTaskSet
        fields = ["expire", "note"]


class CheckTaskSetSerializer(CustomModelSerializer):
    user_duty_name = serializers.CharField(source="user_duty.name", read_only=True)
    myschedule_name = serializers.CharField(source="myschedule.name", read_only=True)
    enabled = serializers.BooleanField(source='periodictask.enabled', read_only=True)
    last_run_at = serializers.DateTimeField(source='periodictask.last_run_at', read_only=True)
    total_run_count = serializers.IntegerField(source='periodictask.total_run_count', read_only=True)

    class Meta:
        model = CheckTaskSet
        fields = '__all__'


class CheckWork_10_CreateUpdateSerializer(CustomModelSerializer):
    category = serializers.PrimaryKeyRelatedField(
        label='检查分类', queryset=Dictionary.objects.filter(type__code='checkwork_category'))

    class Meta:
        model = CheckWork
        fields = ['name', 'description', 'category', 'time_start', 'time_end', 'enabled']

    def save(self, **kwargs):
        kwargs['type'] = 10  # 创建/编辑只有手动类型
        return super().save(**kwargs)


class CheckWorkSerializer(CustomModelSerializer):
    category_name = serializers.CharField(source='category.name', read_only=True)
    user_duty_name = serializers.CharField(source='user_duty.name', read_only=True)
    riskpoint_name = serializers.CharField(source='riskpoint.name', read_only=True)

    class Meta:
        model = CheckWork
        fields = '__all__'


class HazardSerializer(CustomModelSerializer):
    class Meta:
        model = Hazard
        fields = '__all__'