# Create your tasks here
from __future__ import absolute_import, unicode_literals
from apps.utils.tasks import CustomTask
from celery import shared_task
from apps.utils.sql import DbConnection
from server.settings import get_sysconfig
from django.core.cache import cache
from apps.wpm.models import SfLog
from apps.mtm.models import Mgroup
import datetime
from django.db.models import Sum
from apps.wpm.services import make_sflogs
from apps.wpm.models import SfLog, StLog, SfLogExp
from django.utils import timezone
from django.db.models import F


@shared_task(base=CustomTask)
def make_sflogs_simple(days, state_date: str, end_date: str):
    """
    根据班次规则生成今明两天的排班记录
    """
    if days:
        start_date = datetime.datetime.today()
        end_date = start_date + datetime.timedelta(days=days)
    else:
        start_date = datetime.datetime.strptime(state_date, "%Y-%m-%d").date()
        end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d").date()
    mgroups = Mgroup.objects.filter(cate='section', need_enm=True).all()
    for mgroup in mgroups:
        make_sflogs(mgroup, start_date, end_date)


@shared_task(base=CustomTask)
def get_total_hour_now(sflogId: str):
    """
    获取当前总时长, 当传入的是一个sflog时, 返回其total_hour_now
    否则更新所有total_hour_now
    """
    now = timezone.now()
    if sflogId:
        sflog = SfLog.objects.get(id=sflogId)
        if sflog.end_time <= now:
            sflog.total_hour_now = sflog.total_hour
        else:
            total_hour_now = (now-sflog.start_time).total_seconds()/3600
            sflog.total_hour_now = total_hour_now if total_hour_now > 0 else 0
        sflog.save()
        return sflog.total_hour_now
    else:
        SfLog.objects.filter(end_time__lte=now).exclude(
            total_hour_now__lt=F('total_hour')).update(total_hour_now=F('total_hour'))
        sf_qs = SfLog.objects.filter(end_time__gt=now)
        for i in sf_qs:
            total_hour_now = (now-i.start_time).total_seconds()/3600
            i.total_hour_now = total_hour_now if total_hour_now > 0 else 0
            i.save()


@shared_task(base=CustomTask)
def cal_exp_duration_hour(stlogId: str):
    """
    计算异常记录对应的每班持续时间
    """
    from apps.enm.tasks import cal_enstat  # 如果是停机需要进行统计停机时长
    if stlogId:
        stlogs = StLog.objects.filter(id=stlogId)
    else:  # 不传就默认更新所有的
        stlogs = StLog.objects.filter(end_time=None)
    now = timezone.now()
    for stlog in stlogs:
        need_cal_enstat = True
        if stlog.is_shutdown is False:
            need_cal_enstat = False
        st_start = stlog.start_time
        if st_start >= now:
            break
        if stlog.end_time is None:  # 说明异常还未结束,此时也需要计算duration
            st_end = now
        else:
            st_end = stlog.end_time
        sf_qs = SfLog.objects.filter(mgroup=stlog.mgroup)
        sf_qs = (sf_qs.filter(start_time__gte=st_start, start_time__lt=st_end) | sf_qs.filter(end_time__gt=st_start,
                 end_time__lte=st_end) | sf_qs.filter(start_time__lte=st_start, end_time__gte=st_end)).order_by('start_time').distinct()
        SfLogExp.objects.filter(stlog=stlog, sflog__in=sf_qs).delete()
        for ind, sflog in enumerate(sf_qs):
            sflogexp, _ = SfLogExp.objects.get_or_create(stlog=stlog, sflog=sflog, defaults={
                                                         'stlog': stlog, 'sflog': sflog})
            # 计算duration
            sf_end, sf_start = sflog.end_time, sflog.start_time
            duration_item_delta = min(sf_end, st_end) - max(sf_start, st_start)
            total_seconds = duration_item_delta.total_seconds()
            if total_seconds < 0:
                duration_item = 0
            else:
                duration_item = total_seconds/3600
            sflogexp.duration = duration_item
            sflogexp.save()
            if need_cal_enstat:
                # 计算每班的总停机时间
                ret = SfLogExp.objects.filter(
                    sflog=sflog, stlog__is_shutdown=True).aggregate(sum=Sum('duration'))
                if ret.get('sum', 0):
                    sflog.shut_hour = ret['sum']
                    sflog.save()
                    # 更新sflog总时长
                    if sflog.end_time > now:
                        get_total_hour_now(sflog.id)
                    if stlogId:
                        cal_enstat('sflog', sflog.id, sflog.mgroup.id, None, None, None,
                                   None, None, None, None, cascade=True, cal_attrs=['run_hour'])


@shared_task(base=CustomTask)
def cal_enstat_when_pcoal_heat_change(sflogId):
    from apps.enm.models import EnStat
    from apps.enm.tasks import cal_enstat_pcoal_change, cal_enstat2
    sflog = SfLog.objects.get(id=sflogId)

    pcoal_heat = sflog.pcoal_heat
    year_s, month_s, day_s = sflog.get_ymd
    # 只会影响到回转窑及水泥磨数据
    enstats = EnStat.objects.filter(mgroup__name='回转窑', year_s=year_s,
                                    month_s=month_s, day_s=day_s, type__in=['hour_s', 'sflog', 'day_s'])
    for enstat in enstats:
        cal_enstat_pcoal_change(enstat, pcoal_heat)
    enstats_other = EnStat.objects.filter(mgroup__name='回转窑', year_s=year_s, month_s=month_s, type__in=[
                                          'month_st', 'month_s']) | EnStat.objects.filter(mgroup__name='回转窑', year_s=year_s, type__in=['year_s'])
    for enstat in enstats_other:
        cal_enstat_pcoal_change(enstat, pcoal_heat)

    cal_enstat2('day_s', year_s, month_s, day_s)


@shared_task(base=CustomTask)
def cal_enstat_when_team_change(sflogId):
    from apps.enm.tasks import cal_enstat
    sflog = SfLog.objects.get(id=sflogId)
    cal_enstat('month_st', sflogId, sflog.mgroup.id, None,
               None, None, None, None, None, None, False, [])
