from pandas import NaT, Timedelta
from functools import lru_cache
from pred_func import pred_func, reverse_func


# interval_i = [end, start] = [(now-endTime)/hour, (now-startTime)/hour]
# x = (endTime-startTime)/hour = start-end per interval_i  predTime = now-hour(sum(x)) = endTime per interval_i
# t = (now-predTime)/hour  initial = hourBetween = (now-startTimeInitial)/hour = interval[0][1]  ongoing t = t-x
# a = temp of StartTime  inital = RATemp
# b = ambi_temp in interval_i  X = interval_i = [end, start]
# lis_rec = [interval_i, b, t]
# pred_x = (predTimeTargetTemp-startTimeInitial)/hour  startTimeInitial = now-hour(interval[0][1]) = round(df.FinishTime) = df.time
# pred_time = predTimeTargetTemp = startTimeInitial + hour(pred_x)
@lru_cache
def pred_time(RATemp, ambi_temp, coef, interval, time, target_temp):
    t = interval[0][1]
    a = RATemp
    lis_rec = [interval[0], ambi_temp[0]]
    count = 0
    for X, b in zip(interval, ambi_temp):
        if a > target_temp:  # 如果该区间的初始温度>目标温度
            count += 1
            x = X[1] - X[0]  # 预测时长
            a = pred_func(a, b, coef, x)  # 预测温度 作为下个区间的初始温度
            lis_rec = [X, b, t]  # 备份该区间及其环境温度 t=start
            t -= x  # 当前时间-预测时间 = hourBetween-预测时长 = end else in (start, end]  t = now-endTime (per interval_i) if a > target_temp else now-predTime (>= now-endTime)  predTime = endTime else 早于 endTime
        else:  # 如果该区间的初始温度<=目标温度
            X, b, t = lis_rec  # 上个区间及其环境温度
            x = reverse_func(target_temp, a, b, coef)  # 从本区间StartTime达到目标温度的预测时长 = (predTimeTargetTemp-startTime)/hour  startTime in intervalCurrent
            t
            pred_x = x - X[0]  # 当前时间-预测时间 = (now-predTime)/hour
            break

    if a > self.target_temp:
        if count < len(interval):  # 如果遍历中断
            pass
        else:  # 如果遍历全部 仍然高于目标温度
            X, b = lis_rec
            pred_x = self.reverse_f(self.target_temp, a, b, coef)
    else:  # 如果遍历全部 并且是最后一次遍历中达到目标温度
        if count == len(interval):  # 排除for循环中的else语句已经处理了的情况 而是当且仅当
            X = lis_rec
            x = self.reverse_f(self.target_temp, a, b, coef)
            pred_x = x - X[1]
    pred_time = time + Timedelta(hours=interval[0][1] + pred_x)
    return [round(i[1], 1) for i in lis], pred_x, pred_time