from unify_api.constants import SLOTS_15MIN, DUST_STATE
from unify_api.modules.common.dao.common_dao import storey_pl_by_cid, \
    storey_wp_by_cid
from unify_api.modules.common.dao.common_dao import \
     load_point_pttl_mean
from unify_api.modules.common.procedures.points import points_by_storeys
from unify_api.modules.tsp_water.components.drop_dust_cps import DdwResp, \
    DdResp, IrmResp, IosResp, ItiResp, WsStatiResp
from unify_api.modules.tsp_water.dao.drop_dust_dao import \
    query_dust_fogcan_run_state, query_dust_water_run_state, \
    dust_water_run_state_by_time, sum_water_runts_group, sum_kwh_runts_group, \
    dust_water_run_day_sum_water, dust_fogcan_run_day_sum_kwh, sum_water_group
from unify_api.modules.tsp_water.service.tsp_service import day_env_service,\
    day_env_service
from unify_api.utils.common_utils import round_2
from unify_api.utils.time_format import srv_time, last7_day_range, \
    start_end_date
from unify_api.modules.tsp_water.procedures.tsp_pds import  \
    per_hour_wave, per_hour_kwh_wave


async def post_drop_dust_service(storeys):
    """降尘措施-卡片信息"""
    now_date, timestamp = srv_time()
    now_ymd = now_date.split(" ")[0]
    # 1.获取storey信息
    storey_list = await points_by_storeys(storeys)
    # 雾炮point_id
    point_list = [i["point_id"] for i in storey_list if
                  i["storey_name"] == "雾炮"]
    # 喷淋water_id
    water_list = [i["point_id"] for i in storey_list if
                  i["storey_name"] == "喷淋"]
    # 2.mysql取雾炮数据
    dust_dic = {}
    if point_list:
        dust_list = await query_dust_fogcan_run_state(point_list, now_ymd)
        dust_dic = {i["pid"]: i for i in dust_list if i}
    # 3.mysql取喷淋数据
    water_dic = {}
    if water_list:
        water_list = await query_dust_water_run_state(water_list, now_ymd)
        water_dic = {i["water_id"]: i for i in water_list if i}
    # 4.构造返回
    return_data = {}
    for point in storey_list:
        storey_name = point.get("storey_name")
        storey_id = point.get("storey_id")
        point_id = point.get("point_id")
        room_name = point.get("room_name")
        # 4.1 雾炮数据
        if point_id in dust_dic:
            # 日运行时间
            day_run_time = dust_dic[point_id]["day_run_times"]
            # 日累计用电量
            day_kwh = dust_dic[point_id]["day_kwh_diff"]
            # 开启状态
            state = DUST_STATE[dust_dic[point_id]["open_state"]]
            # 构造返回
            res_dic = {
                "room_name": room_name,
                "storey_id": storey_id,
                "point_id": point_id,
                "day_run_time": day_run_time,
                "day_kwh": day_kwh,
                "state": state,
            }
            if storey_name in return_data:
                return_data[storey_name].append(res_dic)
            else:
                return_data[storey_name] = [res_dic]
        # 4.1 喷淋数据
        if point_id in water_dic:
            # 日运行时间
            day_run_time = water_dic[point_id]["day_run_times"]
            # 日用水量
            day_water = water_dic[point_id]["day_water_diff"]
            # 开启状态
            state = DUST_STATE[water_dic[point_id]["open_state"]]
            # 构造返回
            res_dic = {
                "room_name": room_name,
                "storey_id": storey_id,
                "point_id": point_id,
                "day_run_time": day_run_time,
                "day_kwh": day_water,
                "state": state,
            }
            if storey_name in return_data:
                return_data[storey_name].append(res_dic)
            else:
                return_data[storey_name] = [res_dic]
    # 5. 转换成list格式返回
    if return_data:
        # 房间排序, 并返回数据转化为list
        return_list = [{"name": key, "storey_id": value[0]["storey_id"],
                        "room_data": sorted(value,
                                            key=lambda i: i["point_id"])}
                       for key, value in return_data.items()]
        # 楼层排序
        return_list = sorted(return_list, key=lambda x: x["storey_id"])
    else:
        return_list = []
    return DdResp(res_data=return_list)


async def post_drop_dust_wave_service(point_id, start, end):
    """降尘措施-雾炮-运行曲线"""
    # 1. 获取聚合信息
    slots_list = SLOTS_15MIN
    sql_re = await load_point_pttl_mean(start, end, point_id)
    if not sql_re:
        return DdwResp(slots=[], value=[])
    es_re_dic = {str(i["create_time"])[-8:-3]: i for i in sql_re}
    p_list = []
    for slot in slots_list:
        if slot in es_re_dic:
            pttl_mean = round_2(es_re_dic[slot]["pttl_mean"])
            p_list.append(pttl_mean)
        else:
            p_list.append("")
    return DdwResp(slots=slots_list, value=p_list)


async def drop_water_wave_service(point_id, start, end):
    """降尘措施-雾炮-运行曲线"""
    # 1. 获取聚合信息
    slots_list = SLOTS_15MIN
    water_list = await dust_water_run_state_by_time(start, end, point_id)
    if not water_list:
        return DdwResp(slots=[], value=[])
    water_dic = {str(i["quarter_time"]).split(" ")[1][:5]: i for i in
                 water_list}
    water_list = []
    for slot in slots_list:
        if slot in water_dic:
            water_data = round_2(water_dic[slot]["qr_water_diff"])
            water_list.append(water_data)
        else:
            water_list.append("")
    return DdwResp(slots=slots_list, value=water_list)


async def index_run_monit_service(cid):
    """首页-运行监测-统计"""
    now_date, timestamp = srv_time()
    now_ymd = now_date.split(" ")[0]
    # 1. 喷淋
    water_start = 0
    water_stop = 0

    water_list = await storey_pl_by_cid(cid)
    water_id_list = [i["point_id"] for i in water_list]
    water_info = await query_dust_water_run_state(water_id_list, now_ymd)
    # 每个water_id保留最新一条记录
    water_dic = {i["water_id"]: i for i in water_info if i}
    for key, value in water_dic.items():
        state = value["open_state"]
        if state == 0:
            water_stop += 1
        else:
            water_start += 1
    # 2. 雾炮
    gun_start = 0
    gun_stop = 0

    gun_list = await storey_wp_by_cid(cid)
    gun_id_list = [i["point_id"] for i in gun_list]
    gun_info = await query_dust_fogcan_run_state(gun_id_list, now_ymd)
    # 每个gun_id保留最新一条记录
    gun_dic = {i["pid"]: i for i in gun_info if i}
    for key, value in gun_dic.items():
        state = value["open_state"]
        if state == 0:
            gun_stop += 1
        else:
            gun_start += 1
    return IrmResp(
        water={"start": water_start, "stop": water_stop},
        fog_gun={"start": gun_start, "stop": gun_stop},
    )


async def index_op_stat_service(cid):
    """首页-运行统计-扬尘"""
    # 1. 获取最近7天起始时间, 不包括今天
    s, e = last7_day_range()
    start = s.split(" ")[0]
    end = e.split(" ")[0]
    # 2. 喷淋
    # water_id和name关系
    water_list = await storey_pl_by_cid(cid)
    water_map = {water["point_id"]: water for water in water_list}
    # 运行时间和用水量
    water_sum = await sum_water_runts_group(start, end)
    if not water_sum:
        return IosResp(water=[], fog_gun=[])
    water_res = []
    for water in water_sum:
        run_time = round_2(water["SUM(run_ts)"])
        use_water = round_2(water["SUM(water_total)"])
        name = water_map[water["water_id"]]["room_name"]
        water_res.append(
            {"name": name, "run_time": run_time, "use_water": use_water}
        )
    water_res = sorted(water_res, key=lambda x: x["use_water"], reverse=True)
    # 3.雾炮
    gun_list = await storey_wp_by_cid(cid)
    gun_map = {gun["point_id"]: gun for gun in gun_list}
    # 运行时间和用电量
    gun_sum = await sum_kwh_runts_group(start, end)
    gun_res = []
    for gun in gun_sum:
        run_time_gun = round_2(gun["SUM(run_ts)"])
        use_kwh = round_2(gun["SUM(kwh_total)"])
        name_gun = gun_map[gun["pid"]]["room_name"]
        gun_res.append(
            {"name": name_gun, "run_time": run_time_gun, "use_kwh": use_kwh}
        )
    gun_res = sorted(gun_res, key=lambda x: x["use_kwh"], reverse=True)
    return IosResp(
        water=water_res,
        fog_gun=gun_res
    )


async def index_today_info_service(cid):
    """首页-今日数据-扬尘"""
    # 1. 环境信息
    # dr = await day_env_service(cid)
    dr = await day_env_service(cid)
    # 2. 今日用水, 用电
    today_start, today_end, m_start, m_end = start_end_date()
    start = today_start.split(" ")[0]
    end = today_end.split(" ")[0]

    sum_water = await dust_water_run_day_sum_water(start)
    sum_kwh = await dust_fogcan_run_day_sum_kwh(start)
    return ItiResp(
        pm2_5=dr.pm2_5,
        pm10=dr.pm10,
        tsp=dr.tsp,
        today_water=round_2(sum_water["sum(water_total)"]),
        today_kwh=round_2(sum_kwh["sum(kwh_total)"]),
    )


async def index_water_service(start, end, date_type):
    # 用电量 pm2.5 pm10 tsp
    # pm25_list, pm10_list, tsp_list, slots = await per_hour_wave(start, end)
    pm25_list, pm10_list, tsp_list, slots = await per_hour_wave(start, end)
    water_info = await sum_water_group(start, end, date_type)
    water_list = ['' for _ in range(len(slots))]
    for index, info in enumerate(water_info):
        water_list[index] = round_2(info.get("water"))
    return WsStatiResp(
        pm2_5=pm25_list,
        pm10=pm10_list,
        tsp=tsp_list,
        slots=slots,
        water_or_electric=water_list,
    )


async def index_electric_service(cid, start, end):
    storey_list = await storey_wp_by_cid(cid)
    point_list = [storey["point_id"] for storey in storey_list]
    pm25_list, pm10_list, tsp_list, slots = await per_hour_wave(start, end)
    kwh_res, slots = await per_hour_kwh_wave(start, end, point_list)
    return WsStatiResp(
        pm2_5=pm25_list,
        pm10=pm10_list,
        tsp=tsp_list,
        slots=slots,
        water_or_electric=kwh_res,
    )