# -*- coding:utf-8 -*-
"""用电健康指数+健康指数+健康达标率"""

from pot_libs.logger import log
from pot_libs.sanic_api import summary, description
from pot_libs.utils.exc_util import ParamException, DBException, BusinessException
from unify_api.modules.common.procedures import health_score
from unify_api.modules.common.procedures.cids import get_cids, get_proxy_cids
from unify_api.modules.common.procedures.health_score import load_manage_health_radar

from unify_api.modules.home_page.service.health_index_service import \
    health_ctl_rate_service, health_ctl_rate_service_new15
from unify_api.modules.home_page.components.health_index import (
    QueryDetails,
    HealthIndexResp,
    HealthRadarResp,
    HealthCtlRateRes,
    ManageHealthIndexReq,
    ManageHealthIndexResp,
    ProductReq,
)


@summary("用电健康指数")
@description("一天一刷新，统计周期为7天")
async def post_health_index(req, body: QueryDetails) -> HealthIndexResp:
    """获取首页用电健康指数"""
    try:
        cid = body.cid
    except:
        log.error("param error")
        raise ParamException(message="参数错误, cid参数必传!")

    if cid <= 0:
        log.error("param error")
        raise ParamException(message="参数错误, cid参数必须是一个正整数!")

    health_index = await health_score.load_health_index(cid)

    return HealthIndexResp(health_index=health_index)


@summary("健康指数雷达评分")
@description("一天一刷新，统计周期为7天")
async def post_health_radar(req, body: QueryDetails) -> HealthRadarResp:
    """获取健康指数雷达-取15min数据
    注意:
    1.负载率的数据在写入ES15min数据时有做变压器判断逻辑，这里直接读取即可
    2.功率因数：有进线级功率因数时，只计算进线级功率因数
    3.电压谐波畸变：只计算三表法计量点，如果所有监测点都是二表法，则取其他所有指标均值
    """

    cid = body.cid

    if cid <= 0:
        log.error("param error")
        raise ParamException(message="参数错误, cid参数必须是一个正整数!")

    # score_info = await health_score.load_health_radar(cid)
    score_info = await health_score.load_health_radar_new15(cid)

    return HealthRadarResp(
        v_dev=score_info["v_score"],
        freq_dev=score_info["freq_score"],
        ubl=score_info["ubl_score"],
        costtl=score_info["costtl_score"],
        thdu=score_info["thdu_score"],
        lf=score_info["lf_score"],
    )


@summary("健康参数达标率")
@description("每分钟刷新一次")
async def post_health_ctl_rate(req, body: QueryDetails) -> HealthCtlRateRes:
    cid = body.cid
    # return await health_ctl_rate_service(cid)
    return await health_ctl_rate_service_new15(cid)


@summary("管理版用电健康首页健康统计")
@description("安电U管理版本")
async def post_manage_health_index(req, body: ManageHealthIndexReq) -> ManageHealthIndexResp:
    """获取首页用电健康指数"""
    product = body.product
    user_id = req.ctx.user_id
    # cids = await get_cids(user_id, product)
    proxy_id = body.proxy_id
    cids = await get_proxy_cids(user_id, product, proxy_id)
    cid_map = {"excellent_cnt": 0, "good_cnt": 0, "fair_cnt": 0, "bad_cnt": 0}
    if not cids:
        return ManageHealthIndexResp(**cid_map)
    company_score_map = await health_score.load_manage_health_radar(cids)
    company_index_map = await health_score.load_manage_health_index(company_score_map)
    log.info(f"company_index_map={company_index_map}")
    for cid, health_index in company_index_map.items():
        health_index = round(health_index)
        if 90 <= health_index <= 100:
            cid_map["excellent_cnt"] += 1
        elif 75 <= health_index < 90:
            cid_map["good_cnt"] += 1
        elif 60 <= health_index < 75:
            cid_map["fair_cnt"] += 1
        else:
            cid_map["bad_cnt"] += 1
    return ManageHealthIndexResp(**cid_map)


@summary("管理版本健康指数雷达评分")
@description("一天一刷新，统计周期为7天")
async def post_proxy_health_radar(req, body: ProductReq) -> HealthRadarResp:
    """获取健康指数雷达-取15min数据
    注意:
    1.负载率的数据在写入ES15min数据时有做变压器判断逻辑，这里直接读取即可
    2.功率因数：有进线级功率因数时，只计算进线级功率因数
    3.电压谐波畸变：只计算三表法计量点，如果所有监测点都是二表法，则取其他所有指标均值
    """
    product = body.product
    user_id = req.ctx.user_id
    req_cid = body.cid
    if not req_cid:
        # cids = await get_cids(user_id, product)
        proxy_id = body.proxy_id
        cids = await get_proxy_cids(user_id, product, proxy_id)
    else:
        cids = [req_cid]
    company_score_map = await load_manage_health_radar(cids, recent_days=7)

    total_v_score = 0
    total_freq_score = 0
    total_ubl_score = 0
    total_costtl_score = 0
    total_thdu_score = 0
    total_lf_score = 0
    cid_cnt = 0
    for cid, score_info in company_score_map.items():
        if score_info is None:
            log.error(f"cid = {cid}load_health_index fail")
            continue
        cid_cnt += 1
        total_v_score += score_info["v_score"]
        total_freq_score += score_info["freq_score"]
        total_ubl_score += score_info["ubl_score"]
        total_costtl_score += score_info["costtl_score"]
        total_thdu_score += score_info["thdu_score"]
        total_lf_score += score_info["lf_score"]

    return HealthRadarResp(
        v_dev=total_v_score / cid_cnt if cid_cnt else 100,
        freq_dev=total_freq_score / cid_cnt if cid_cnt else 100,
        ubl=total_ubl_score / cid_cnt if cid_cnt else 100,
        costtl=total_costtl_score / cid_cnt if cid_cnt else 100,
        thdu=total_thdu_score / cid_cnt if cid_cnt else 100,
        lf=total_lf_score / cid_cnt if cid_cnt else 100,
    )
