from collections import defaultdict

from pot_libs.mysql_util.mysql_util import MysqlUtil
from unify_api.modules.common.components.list_points_cps import CommonLocation, \
    CommonPoint, Inline, ListPointResponse
from unify_api.modules.common.dao.common_dao import query_points_by_storey


async def load_compy_points(cids):
    sql = "SELECT p.pid,p.cid,p.inlid,vc,ctnum " \
          "FROM `point` p INNER JOIN " \
          "monitor m on m.mtid=p.mtid where p.cid in %s and m.demolished=0;"
    async with MysqlUtil() as conn:
        points = await conn.fetchall(sql, args=(cids,))
    company_point_map = defaultdict(dict)
    for point in points:
        company_point_map[point["cid"]][point["pid"]] = point
    return company_point_map


async def get_points_num(cid):
    sql = "SELECT count(1) doc_count FROM `point` p LEFT JOIN monitor m " \
          "on m.mtid=p.mtid where m.demolished=0 and m.cid=%s"
    async with MysqlUtil() as conn:
        datas = await conn.fetchone(sql, args=(cid,))
    return datas["doc_count"]


async def proxy_points(cid_list):
    """获取代理下的所有监测点"""
    sql = "SELECT COUNT(p.pid) from point p LEFT JOIN monitor m " \
          "on p.mtid=m.mtid where p.cid in %s and m.demolished=0"
    async with MysqlUtil() as conn:
        num = await conn.fetch_value(sql, args=(tuple(cid_list),))
    return num


async def get_meter_by_point(point_id):
    """
        根据point获取设备数据
    """
    async with MysqlUtil() as conn:
        sql = "SELECT sid, meter_no,m.mtid FROM `point` p LEFT JOIN monitor " \
              "m on m.mtid=p.mtid where m.demolished=0 and p.pid=%s"
        meter_info = await conn.fetchone(sql, args=(point_id,))
        return meter_info


async def list_point(cid):
    list_point = []
    points = {}
    groups = {}
    sql = "SELECT pid, name, add_to_company FROM point WHERE cid=%s"
    async with MysqlUtil() as conn:
        result = await conn.fetchall(sql, args=(cid,))
        for res in result:
            pid = res.get("pid")
            points[pid] = res

    sql = "SELECT id, `group`, item FROM location WHERE cid=%s and `type` in %s"
    async with MysqlUtil() as conn:
        result = await conn.fetchall(sql, args=(
            cid, ["temperature", "residual_current"]))
        for res in result:
            id = res.get("id")
            group = res.get("group")
            item = res.get("item")
            groups.setdefault(group, []).append((id, item))

    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)
            comm_location = {"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)
        comm_point = {"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 {"points": list_point, "inlines": inline_list}


async def point_to_mid(points):
    """获取所有poin_id和mid对应关系"""
    sql = "SELECT pid, mtid FROM point WHERE pid IN %s " \
          "order by pid, create_time"
    async with MysqlUtil() as conn:
        change_meter_records = await conn.fetchall(sql, args=(tuple(points),))
    point_mid_map = {
        i["pid"]: i["mtid"] for i in change_meter_records
    }
    point_mid = dict(filter(lambda x: x[1] is not None, point_mid_map.items()))
    return point_mid, len(point_mid)


async def points_by_storeys(cid, storeys):
    """根据storey_id查询point_id和room_name"""
    point_list = await query_points_by_storey(cid, storeys)
    return point_list
