from pot_libs.logger import log
from pot_libs.sanic_api import summary
from pot_libs.mysql_util.mysql_util import MysqlUtil
from unify_api.modules.common.components.common_cps import CidReq
from unify_api.modules.common.procedures.points import point_to_mid
from unify_api.modules.common.service.list_point_service import \
    list_storey_service, list_tsp_point_service, list_point_level_service, \
    list_point_inline_service
from unify_api.modules.common.components.list_points_cps import (
    ListPointRequest,
    ListPointResponse,
    CommonPoint,
    CommonLocation,
    Inline, LsRep, LtpRep, LplResp, LpiResp)


# @summary('获取监测点,进线列表')
# async def post_list_point(req, body: ListPointRequest) -> ListPointResponse:
#     cid = body.cid
#     list_point, inline_list, points = [], [], {}
#     sql = "SELECT pid,name,mtid,inlid,add_to_company FROM point where cid=%s"
#     async with MysqlUtil() as conn:
#         result = await conn.fetchall(sql, args=(cid,))
#     add_to_company = []
#     for res in result:
#         # mtids.append(res["mtid"])
#         inline_list.append({"inline_id": res["inlid"], "name": res["name"]})
#         points[res["mtid"]] = res
#         add_to_company.append(res["add_to_company"])
#     if points:
#         if len(points) == 1:
#             l_sql = f"SELECT mtid,lid,ad_field from location " \
#                     f"where mtid = {list(points.keys())[0]}"
#         else:
#             l_sql = f"SELECT mtid,lid,ad_field from location " \
#                     f"where mtid in {tuple(points.keys())}"
#         async with MysqlUtil() as conn:
#             datas = await conn.fetchall(l_sql)
#         for data in datas:
#             if data["mtid"] in points.keys():
#                 temp_dict = {"temp1": "A相", "temp2": "B相", "temp3": "C相",
#                              "temp4": "N相", "residual_current": "default"}
#                 flag = temp_dict.get(data["ad_field"]) or ""
#                 locations_dict = {
#                     "item": flag,
#                     "location_id": data.get("lid")
#                 }
#                 if "locations" not in points[data["mtid"]]:
#                     points[data["mtid"]]["locations"] = [locations_dict]
#                 else:
#                     points[data["mtid"]]["locations"].append(locations_dict)
#         for k, v in points.items():
#             list_point.append({
#                 "name":  v["name"], "point_id": v["pid"],
#                 "locations": v.get("locations") or [],
#                 "add_to_company": v["add_to_company"]
#             })
#     return ListPointResponse(
#         points=list_point,
#         inlines=inline_list,
#         power_show_all=1 if any(add_to_company) else 0
#     )
@summary('获取监测点,进线列表')
async def post_list_point(req, body: ListPointRequest) -> ListPointResponse:
    cid = body.cid
    if not cid or cid < 0:
        return ListPointResponse().param_error()
    is_power_equipment = body.is_power_equipment
    list_point = []
    points = {}
    groups = {}
    # 查询属于当前工厂下的监测点 + 其他工厂但是被复用到当前工厂的监测点
    if not is_power_equipment:
        sql = "SELECT p.pid,p.mtid, p.name, p.add_to_company FROM point p " \
              "left join monitor_reuse m on p.mtid = m.mtid " \
              "WHERE p.cid=%s or m.cid = %s"
    else:
        # 动力设备
        sql = "SELECT p.pid,p.mtid, p.name, p.add_to_company FROM point p " \
              "left join monitor m on p.mtid = m.mtid " \
              "left join monitor_reuse mr on p.mtid = mr.mtid " \
              "WHERE m.demolished = 0 and m.is_power_equipment = 1 and (" \
              "p.cid=%s or mr.cid = %s)"

    async with MysqlUtil() as conn:
        result = await conn.fetchall(sql, args=(cid, cid))
    # 去调拆表的POINT
    point_ids = [point["pid"] for point in result]
    point_mid_map, point_count = await point_to_mid(point_ids)
    result = [point for point in result if point["pid"] in point_mid_map]

    for res in result:
        pid = res.get("pid")
        points[pid] = res

    # 获取相应的mtid
    point_map_mtids = [point["mtid"] for point in result if
                       point['pid'] in point_mid_map]

    # 根据pid获取mtd
    sql = "SELECT ln.lid, mr.`name` `group`, ln.item FROM location ln LEFT JOIN" \
          "  monitor mr on ln.mtid = mr.mtid   WHERE ( ln.cid=%s or ln.mtid in " \
          "%s ) and ln.`ad_type` in %s"

    try:
        async with MysqlUtil() as conn:
            result = await conn.fetchall(sql, args=(
                cid, point_map_mtids, ["temperature", "residual_current"]))
            for res in result:
                id = res.get("lid")
                group = res.get("group")
                item = res.get("item")
                groups.setdefault(group, []).append((id, item))
    except Exception as e:
        log.exception(e)
        return ListPointResponse().db_error()

    for pid, point_info in points.items():
        name = point_info.get("name")
        add_to_company = point_info["add_to_company"]
        items = groups.get(name, [])
        locations = []
        for id, item in items:
            comm_location = CommonLocation(location_id=id, item=item)
            locations.append(comm_location)
        comm_point = CommonPoint(name=name, point_id=pid, locations=locations,
                                 add_to_company=add_to_company)
        list_point.append(comm_point)

    async with MysqlUtil() as conn:
        sql = "SELECT inlid, `name` FROM inline WHERE cid=%s"
        inlines = await conn.fetchall(sql, args=(cid,))
        inline_list = [Inline(inline_id=inline["inlid"], name=inline["name"])
                       for inline in inlines]
    return ListPointResponse(
        points=list_point,
        inlines=inline_list,
        power_show_all=1 if any(
            i for i in list_point if i.add_to_company == 1) else 0
    )


@summary('获取楼层-识电u')
async def post_list_storey(req, body: ListPointRequest) -> LsRep:
    cid = body.cid
    return await list_storey_service(cid)


@summary('获取TSP监测点-扬尘')
async def post_list_tsp_point(req, body: ListPointRequest) -> LtpRep:
    cid = body.cid
    return await list_tsp_point_service(cid)


@summary('新版监测点-包含进线变压器层级')
async def post_list_point_level(req, body: CidReq) -> LplResp:
    cid = body.cid
    return await list_point_level_service(cid)


@summary('新版监测点-进线')
async def post_list_point_inline(req, body: CidReq) -> LpiResp:
    cid = body.cid
    return await list_point_inline_service(cid)
