from math import radians, cos, sin, asin, sqrt
import pandas as pd
import numpy as np
from datetime import datetime
from datetime import timedelta

from GpsRank import *
from ProcessDfBms import *
from ProcessDfGps import *

from LIB.BACKEND import DBManager
#####################################配置环境分割线#################################################

def GetDistInfo(input_sn,input_starttime,input_endtime):

    #####################################配置参数分割线#################################################
    dbManager = DBManager.DBManager()
    data_raw = dbManager.get_data(sn=input_sn, start_time=input_starttime, 
        end_time=input_endtime)
    #拆包预处理
    df_bms_raw=data_raw['bms']
    df_gps_raw=data_raw['gps']
    df_bms=preprocess_Df_Bms(df_bms_raw)
    df_gps=preprocess_Df_Gps(df_gps_raw)
    
    #####################################数据预处理分割线#################################################

    # mode: 0：正常取数； 1：7255 取数
    if input_sn[0:2] == 'UD' or input_sn[0:2] == 'MG':
        mode = 1
    else:
        mode = 0
    #获取状态表,mode默认为0,mode=1放电时电流为负，mode=0充电时电流为正

    df_bms_drive_timetable=get_bms_drive_timetable(df_bms,mode)
    df_gps_drive_cycle_accum=pd.DataFrame()
    if len(df_bms_drive_timetable)>0:
        for index in range(len(df_bms_drive_timetable)):
            #筛选drivecycle数据
            drive_start_time=df_bms_drive_timetable.loc[index,'drive_start_time']#开始时间
            drive_end_time=df_bms_drive_timetable.loc[index,'drive_end_time']#结束时间

            time_condition=(df_gps['time']>drive_start_time)&(df_gps['time']<drive_end_time)#时间判断条件
            df_gps_drive_cycle=df_gps.loc[time_condition,:].copy()
            df_gps_drive_cycle=df_gps_drive_cycle.reset_index(drop=True)#重置index
            #计算drivecycle GPS累计里程,存入表格
            condition_a=df_gps_drive_cycle['deltatime']>60*3
            condition_b=(df_gps_drive_cycle['deltatime']>90*1)&(df_gps_drive_cycle['distance']>1000)
            drive_cycle_dist_array=df_gps_drive_cycle.loc[~(condition_a|condition_b),'distance'].values
            drive_cycle_dist_array=drive_cycle_dist_array[np.where((drive_cycle_dist_array>=1)&(drive_cycle_dist_array<1000))[0]]
            gps_dist=drive_cycle_dist_array.sum()
            df_bms_drive_timetable.loc[index,'gps_dist']=gps_dist#得到GPS路径
            #计算头-尾的空缺时间段对应的预估SOC
            if len(df_gps_drive_cycle)>2:
                gps_starttime=df_gps_drive_cycle.loc[1,'time']#gps开始时间
                gps_endtime=df_gps_drive_cycle.loc[df_gps_drive_cycle.index[-1],'time']#gps结束时间
                #从drive_start_time到gps开始时间，使用SOC计算的里程
                #gps结束时间到drive_end_time，使用SOC计算的里程
                unrecorded_odo_head=cal_deltasoc(df_bms,drive_start_time,gps_starttime)
                unrecorded_odo_tail=cal_deltasoc(df_bms,gps_endtime,drive_end_time)
            else:
                #计算数据丢失行unrecordeodo
                unrecorded_odo_head=cal_deltasoc(df_bms,drive_start_time,drive_end_time)
                unrecorded_odo_tail=0
            #计算中间的预估SOC
            predict_dist=cal_unrecorded_gps(df_gps_drive_cycle,df_bms)
            #计算总的预估SOC
            totaldist=predict_dist+unrecorded_odo_head+ unrecorded_odo_tail#得到GPS路径
            df_bms_drive_timetable.loc[index,'predict_dist']=totaldist
    else :
        pass

    #####################################统计行驶里程End#################################################
    #打印输出结果#
    index_list=list(range(len(df_bms_drive_timetable)))

    dist_gps=0
    dist_predict=0
    day_start_time=''#当日开始时间
    day_end_time=''#当日结束时间
    day_start_soc=0#当日开始soc
    day_end_soc=0#当日结束soc
    day_min_soc=101#当日最低soc
    drive_accum_soc=0#累计使用SOC

    if len(df_bms_drive_timetable)>0:
        #开始行
        day_start_soc=df_bms_drive_timetable.loc[1,'drive_start_soc']#开始soc
        day_start_time=df_bms_drive_timetable.loc[1,'drive_start_time']#开始时间
        #结束行
        day_end_time=df_bms_drive_timetable.loc[len(df_bms_drive_timetable)-1,'drive_end_time']#结束时间
        day_end_soc=df_bms_drive_timetable.loc[len(df_bms_drive_timetable)-1,'drive_end_soc']#结束soc

    for index in index_list:
        '''汇总里程'''
        dist_gps+=df_bms_drive_timetable.loc[index,'gps_dist']/1000#计算GPS里程
        dist_predict+=df_bms_drive_timetable.loc[index,'predict_dist']#计算预估里程
        drive_start_soc=df_bms_drive_timetable.loc[index,'drive_start_soc']#驾驶周期开始的soc
        drive_end_soc=df_bms_drive_timetable.loc[index,'drive_end_soc']#驾驶周期结束的soc
        day_min_soc=min(day_min_soc,drive_start_soc,drive_end_soc)

        delta_soc=drive_start_soc-drive_end_soc#驾驶周期SOC变化量
        drive_accum_soc+=abs(delta_soc)#所有drive cycle累计消耗的soc

    # gps_score=get_df_gps_score(input_starttime,input_endtime,df_gps)
    # gps_score=round(gps_score,1)
    #计算总里程
    dist_gps=round(dist_gps,3)
    dist_predict=round(dist_predict,3)
    dist_all=round(dist_gps+dist_predict,3)
    #输出统计结果
    # print ('为您查询到，从'+input_starttime+'到'+input_endtime+'时间段内：')
    # print('SOC变化量：'+str(df_bms['bmspacksoc'].max()-df_bms['bmspacksoc'].min())+' %')
    # print('行驶总里程:'+str(dist_all)+' km')

    return {'SN':input_sn,'range':dist_all,'accum_soc':drive_accum_soc,'day_start_soc':day_start_soc,
    'day_end_soc':day_end_soc,'day_start_time':day_start_time,'day_end_time':day_end_time,
    'day_min_soc':day_min_soc}
    # print('其中GPS信号在线时里程:'+str(dist_gps)+' km')
    # print('其中GPS信号掉线时预估里程:'+str(dist_predict)+' km')
    # print('GPS信号质量评分为：'+str(gps_score),'分\n')

    #####################################打印结果End#################################################


