# -*- coding:utf-8 -*-
#
# Author:jing
# Date: 2020/7/9
import json

from pot_libs.aiohttp_util.aiohttp_utils import AioHttpUtils
from pot_libs.mysql_util.mysql_util import MysqlUtil
from pot_libs.common.components.responses import Success
from pot_libs.sanic_api import summary, examples
from pot_libs.logger import log
from pot_libs.settings import SETTING
from pot_libs.utils.exc_util import BusinessException
from unify_api.constants import EVENT_TYPE_SYNC_DEVICE, RESIDUAL_CURRENT_OP
from unify_api.modules.alarm_manager.components.alarm_setting import (
    AlarmSettingUpdate,
    PointAlarmSettingRequest,
    PointAlarmSettingResponse,
    AlarmSetting,
    point_alarm_setting_example
)
from unify_api.modules.alarm_manager.service.alarm_setting_service import \
    post_update_alarm_emq_service


@summary('获取某监测点告警设置列表')
@examples(point_alarm_setting_example)
async def post_point_alarm_setting(req, body: PointAlarmSettingRequest) \
        -> PointAlarmSettingResponse:
    point_id = body.point_id
    location_ids = body.location_ids
    enable = body.enable
    point_alarm_settings = []
    location_alarm_settings = []
    if enable in (0, 1):
        sql_point = "SELECT s.id,s.etype,s.threshold,s.duration,s.enable," \
                    "e.name,e.importance FROM soe_config_record s " \
                    "INNER JOIN event_type e ON s.etype=e.e_type  " \
                    "WHERE s.pid=%s AND s.enable=%s"

        sql_location = "SELECT l.item,s.id,s.etype,e.name,e.importance, " \
                       "s.threshold, s.duration, s.enable " \
                       "FROM soe_config_record s INNER JOIN event_type e " \
                       "ON s.`etype`=e.e_type INNER JOIN location l " \
                       "on l.lid=s.lid " \
                       "WHERE s.lid IN %s AND s.enable=%s"
    else:
        sql_point = "SELECT s.id, s.etype, e.name, e.importance, " \
                    "s.threshold, s.duration, s.enable " \
                    "FROM soe_config_record s INNER JOIN event_type e " \
                    "ON s.`etype`=e.e_type " \
                    "WHERE s.pid=%s"
        sql_location = "SELECT l.item,l.ad_type as location_type,s.id, " \
                       "s.etype,e.name,e.importance,s.threshold,s.duration, " \
                       "s.enable FROM soe_config_record s INNER JOIN " \
                       "event_type e ON s.`etype`=e.e_type INNER JOIN " \
                       "location l on l.lid=s.lid WHERE s.lid IN %s"
    try:
        async with MysqlUtil() as conn:
            if enable in (0, 1):
                res_point = await conn.fetchall(sql_point, args=(
                    point_id, enable,)) if point_id else {}
                res_location = await conn.fetchall(sql_location, args=(
                    tuple(location_ids), enable,)) if location_ids else {}
            else:
                res_point = await conn.fetchall(sql_point, args=(
                    point_id,)) if point_id else {}
                res_location = await conn.fetchall(sql_location, args=(
                    tuple(location_ids),)) if location_ids else {}
            for res in res_point:
                alarm_setting = AlarmSetting(
                    id=res.get("id"),
                    type=res.get("etype"),
                    name=res.get("name"),
                    level=res.get("importance"),
                    threshold=res.get("threshold"),
                    duration=res.get("duration", None),
                    enable=res.get("enable"),
                )
                point_alarm_settings.append(alarm_setting)

            for res in res_location:
                alarm_setting = AlarmSetting(
                    id=res.get("id"),
                    type=res.get("etype"),
                    name=(res.get("item") + res.get("name")) if res.get(
                        "item") != "default" else res.get("name"),
                    level=res.get("importance"),
                    threshold=res.get("threshold"),
                    duration=res.get("duration", None),
                    enable=res.get("enable"))
                location_alarm_settings.append(alarm_setting)
    except Exception as e:
        log.exception(e)
        return PointAlarmSettingResponse().db_error()
    residual_current_op = 0
    user_id = req.ctx.user_id
    if user_id in RESIDUAL_CURRENT_OP:
        residual_current_op = 1
    return PointAlarmSettingResponse(
        residual_current_op=residual_current_op,
        point_alarm_settings=point_alarm_settings,
        location_alarm_settings=location_alarm_settings
    )


# @summary('更新告警设置')
# async def post_update_alarm(req, body: AlarmSettingUpdate) -> Success:
#     id = body.id
#     threshold = body.threshold
#     duration = body.duration
#     enable = body.enable
#     cid = body.cid
#     # user_id = 88
#     user_id = req.ctx.user_id
#     alarm_cid_dic = SETTING.alarm_cid
#     # 1. 判断黑名单
#     # 逻辑: 工厂为99且user_id在[88, 16]中
#     if cid in alarm_cid_dic:
#         user_lis = alarm_cid_dic.get(cid)
#         if user_id in user_lis:
#             return Success(success=0, message="用户工厂在黑名单")
#     # 2. 调用后台接口，传数给装置
#     async with MysqlUtil() as conn:
#         query_sql = "select `point_id`, `location_id`, `type` " \
#                     "from `alarm_setting` where `id`=%s"
#         alarm_map = await conn.fetchone(query_sql, args=(id,))
#     if not alarm_map:
#         raise BusinessException(message=f"正在设置的报警设置id={id}不存在")
#
#     if alarm_map and EVENT_TYPE_SYNC_DEVICE[alarm_map["type"]]:
#         req_json = {
#             "events": [
#                 {
#                     k: v for k, v in {
#                         "point_id": alarm_map["point_id"],
#                         "location_id": alarm_map["location_id"],
#                         "event_type": alarm_map["type"],
#                         "threshold": threshold,
#                         "duration": duration,
#                         "enable": enable,
#                     }.items() if v is not None}]}
#         try:
#             log.info(
#                 f"post_update_alarm url={SETTING.event_post_url} "
#                 f"req_json = {req_json}")
#             resp_str, status = await AioHttpUtils().post(
#                 SETTING.event_post_url,
#                 req_json,
#                 timeout=50,
#             )
#             log.info(f"post_update_alarm resp_str={resp_str} status={status}")
#             resp = json.loads(resp_str)
#         except Exception as e:
#             log.exception(e)
#             return Success(success=0, message=f"操作失败{str(e)}")
#
#         if resp[0].get("timeout"):
#             return Success(
#                 message=f"操作失败status=error, error_data={resp[0]['timeout']}",
#                 success=0)
#         if resp[0].get("status_code") == 500:
#             return Success(message="操作失败status=error, status_code=500",
#                            success=0)
#
#     if duration:
#         sql = "UPDATE alarm_setting " \
#               "SET threshold=%s, duration=%s, `enable`=%s " \
#               "WHERE id=%s"
#         sql_args = (threshold, duration, enable, id,)
#     else:
#         sql = "UPDATE alarm_setting SET threshold=%s, `enable`=%s WHERE id=%s"
#         sql_args = (threshold, enable, id,)
#     try:
#         async with MysqlUtil() as conn:
#             modified_cnt = await conn.execute(sql, args=sql_args)
#             log.info(f"UPDATE alarm_setting modified_cnt={modified_cnt}")
#             # 这里执行一个update,result 返回modified_cnt， 当result=0时也是成功的，因为没引发异常
#             return Success(success=1, message="操作成功")
#     except Exception as e:
#         log.exception(e)
#         return Success(success=0, message=f"操作失败{str(e)}")


@summary('更新告警设置-直接与装置通信')
async def post_update_alarm(req, body: AlarmSettingUpdate) -> Success:
    set_id = body.id  # alarm_setting表id
    threshold = body.threshold
    duration = body.duration
    enable = body.enable
    cid = body.cid
    user_id = req.ctx.user_id
    # user_id = 88
    alarm_cid_dic = SETTING.alarm_cid
    return await post_update_alarm_emq_service(set_id, threshold, duration,
                                               enable, cid, user_id,
                                               alarm_cid_dic)
