from unify_api.modules.zhiwei_u import config
from uuid import uuid4
from pot_libs.qingstor_util.qs_client import QsClient
from pot_libs.aiokafka_util.kafka_util import KafkaUtils
from unify_api.constants import DOWNLOAD_ORDER
from unify_api.modules.zhiwei_u.dao.order_operations_dao import *
from unify_api.modules.zhiwei_u.dao.warning_operations_dao import get_username
from unify_api.modules.zhiwei_u.components.warning_operations_cps import \
    SelectUserResp, Success, SuccessResp
from unify_api.modules.zhiwei_u.components.order_operations_cps import \
    SidToOrderResp, CidToSidResp
from unify_api.modules.zhiwei_u.dao.warning_operations_dao import \
    insert_order_data
from unify_api.modules.zhiwei_u.dao.data_operations_dao import \
    select_point_by_mtid
from unify_api.modules.zhiwei_u.procedures.common import get_order_num, \
    upload_file
from unify_api.modules.zhiwei_u.procedures.common import allowed_file
from unify_api.modules.zhiwei_u.procedures.common import get_all_user


async def w_origin_service():
    info = await w_origin_dao()
    user_info = await get_all_user()
    data = []
    for i in info:
        data.append({
            "create_user_id": i["create_user_id"],
            "user_name": user_info[i["create_user_id"]]["user_name"]
        })
    return SelectUserResp(data=data)


async def search_all_user_service():
    data = await search_all_user_dao()
    return SelectUserResp(data=data)


async def receive_order_service(id, user_id):
    """接单"""
    is_order = await get_order_state_by_id(id)
    if not is_order:
        return Success(success=0, message="该单号不存在")
    user = await get_username(user_id)
    op_record = f"{user['user_name']}接单"
    # 工单表填入 userid 以及修改状态
    await update_order_userid(id, user_id, config.ORDER_WORKING)
    # 流程表添加流程
    await insert_order_detail(id, op_record, user_id)
    dic_data = {
        "order_num": is_order["order_num"],
        "project": config.PRODUCT[is_order["prod_id"]],
        "point": is_order["monitor_name"],
        "sid": is_order["sid"],
        "order_content": is_order["warn_info"],
        "notice_content": "您已接单，请及时处理",
        "user_list": [user_id]
    }
    await KafkaUtils.send_msg(topic="power_iot.push.wechat_operation_order",
                              dic_data=dic_data)
    return Success(success=1, message="操作成功")


async def flow_order_user_service():
    """转单  获取名单"""
    user = await search_all_user_dao()
    return SelectUserResp(data=user)


async def flow_order_service(myself_id, id, user_id, explain, doc_ids):
    """转单"""
    user = await get_username(user_id)
    if myself_id == user_id:
        return Success(success=0, message="转单不能转给自己")
    if not user:
        return Success(success=0, message="未找到用户")
    is_order = await get_order_state_by_id(id)
    if not is_order:
        return Success(success=0, message="该单号不存在")
    myself = await get_username(myself_id)
    op_record = f"{myself['user_name']}转单给{user['user_name']}"
    # 工单表填入 userid
    await update_order_userid(id, user_id, config.ORDER_WORKING)
    # 流程表添加流程
    await insert_order_detail(id, op_record, user_id, explain)
    # 附件表添加附件
    detail_data = await get_detail_id(id, op_record, user_id)
    for doc_id in doc_ids:
        await insert_one_order_files("order_details_id", detail_data["id"],
                                     doc_id)
    dic_data = {
        "order_num": is_order["order_num"],
        "project": config.PRODUCT[is_order["prod_id"]],
        "point": is_order["monitor_name"],
        "sid": is_order["sid"],
        "order_content": is_order["warn_info"],
        "notice_content": "已转单给您，请及时处理",
        "user_list": [user_id]
    }
    await KafkaUtils.send_msg(topic="power_iot.push.wechat_operation_order",
                              dic_data=dic_data)
    return Success(success=1, message="操作成功")


async def work_order_service(id, user_id, explain, doc_ids):
    """处理工单"""
    is_order = await get_order_state_by_id(id)
    if not is_order:
        return Success(success=0, message="该单号不存在")
    user = await get_username(user_id)
    op_record = f"{user['user_name']}处理工单"
    await insert_order_detail(id, op_record, user_id, explain)
    # 附件表添加附件
    detail_data = await get_detail_id(id, op_record, user_id)
    for doc_id in doc_ids:
        await insert_one_order_files("order_details_id", detail_data["id"],
                                     doc_id)
    return Success(success=1, message="操作成功")


async def close_order_service(id, user_id, explain, doc_ids):
    """关闭工单"""
    user = await get_username(user_id)
    if user["role"] == 2:
        data = await get_order_state_by_id(id)
        if not data:
            return Success(success=0, message="该单号不存在")
        op_record = f"{user['user_name']}关闭工单"
        await insert_order_detail(id, op_record, user_id, explain)
        await update_order_state_dao(id, config.ORDER_CLOSE)
        # 附件表添加附件
        detail_data = await get_detail_id(id, op_record, user_id)
        for doc_id in doc_ids:
            await insert_one_order_files("order_details_id", detail_data["id"],
                                         doc_id)

        handle_user_list = await order_detail_flow_by_id(id)
        dic_data = {
            "order_num": data["order_num"],
            "project": config.PRODUCT[data["prod_id"]],
            "point": data["monitor_name"],
            "sid": data["sid"],
            "order_content": data["warn_info"],
            "notice_content": "该工单已关闭，感谢您的配合",
            "user_list": [handle_user["handle_user_id"]
                          for handle_user in handle_user_list]
        }
        await KafkaUtils.send_msg(topic="power_iot.push.wechat_operation_order",
                                  dic_data=dic_data)
        return Success(success=1, message="操作成功")
    else:
        return Success(success=0, message="操作失败，您的权限不足")


async def sid_to_order_service(sid):
    """录入工单  根据sid返回客户信息"""
    datas = await sid_to_order_dao(sid)
    if not datas:
        return Success(success=0, message=f"{sid}未有数据与之匹配")
    for data in datas:
        data["product"] = config.PRODUCT[data["prod_id"]]
    return SidToOrderResp(data=datas)


async def pid_to_sid_service(pid):
    """录入工单  根据监测点pid返回硬件编号sid"""
    sid = await cid_to_sid_dao(pid)
    return CidToSidResp(sid=sid)


async def add_order_service(params, id, user_id, prod_id, cid, check_dt,
                            sid, point_id, doc_ids):
    """录入工单 """
    if not all([prod_id, cid, check_dt]):
        return Success(success=0, message="传入参数缺少必传参数")
    # 同时传监测点和硬件编号 检测
    if all([sid, point_id]):
        is_having = await sid_is_pid(sid, point_id)
        if not is_having:
            return Success(success=0, message="检测点和硬件编号不匹配")
    mon_data = {}
    company = await select_cname_by_cid(cid)
    if point_id:
        mon_data = await get_monitor_by_pid(cid, point_id)
    if not mon_data and sid:
        mon_data = await get_monitor_by_sid(sid)
    # 构建数据
    data = {
        "cid": params.get("cid"),
        "compy_name": company.get("shortname"),
        "sid": params.get("sid"),
        "mtid": mon_data.get("mtid"),
        "monitor_name": mon_data.get("name"),
        "w_type": config.ERROR_TYPE_MANU,
        "warn_info": params.get("warn_info", None),
        "check_dt": params.get("check_dt"),
        "prod_id": params.get("prod_id"),
        "create_user_id": user_id,
        "w_origin": config.W_ORIGIN_MANU,
    }
    if id:
        order = await get_order_state_by_id(id)
        order_num = order["order_num"]
        if order["state"] != 1:
            return Success(success=0, message="该工单状态不是待接单状态")
        # 修改工单
        li = [f"order_num='{order_num}'"]
        for key, value in data.items():
            if value is not None:
                li.append(f"{key}='{value}'")
        conn_sql = ", ".join(li)
        await update_order_by_id(conn_sql, id)
        # 插入修改记录
        user = await get_username(user_id)
        op_record = f"{user['user_name']}修改了工单"
        await insert_order_detail(id, op_record, user_id)
    else:
        # 创建工单
        w_origin = config.W_ORIGIN_MANU
        order_num = get_order_num(w_origin)
        await insert_order_data(data, w_origin, order_num, user_id)
        order_data = await order_num_is_having(order_num)
        id = order_data["id"]
        handle_user_list = await search_all_handle_user_dao()
        dic_data = {
            "order_num": order_num,
            "project": company.get("shortname"),
            "point": mon_data.get("name"),
            "sid": params.get("sid"),
            "order_content": params.get("warn_info", None),
            "notice_content": "已生成一条工单，请及时接单处理",
            "user_list": [handle_user["user_id"]
                          for handle_user in handle_user_list]
        }
        await KafkaUtils.send_msg(
            topic="power_iot.push.wechat_operation_order",
            dic_data=dic_data)
    # 插入附件
    if doc_ids:
        for doc_id in doc_ids:
            await insert_one_order_files("order_record_id", id, doc_id)
    return Success(success=1, message="操作成功")


async def order_detail_service(id):
    """工单详情"""
    data = await order_detail_by_id(id)
    if not data:
        return Success(success=0, message="该工单状态不存在")
    if data["w_type"] == 4:
        user = await get_username(data["create_user_id"])
        data["origin"] = f"{user['user_name']}手动录入"
        data["doc"] = await get_file_by_record_id("order_record_id", id)
    else:
        data["origin"] = "运维报警"
    data["product"] = config.PRODUCT[data["prod_id"]]
    data["check_dt"] = data["check_dt"].strftime("%Y-%m-%d %H:%M")
    if data["mtid"]:
        point = await select_point_by_mtid(data["mtid"])
        data["pid"] = point["pid"]
    return SidToOrderResp(data=data)


async def order_detail_flow_service(id):
    """工单详情 流程"""
    order_data = await order_detail_by_id(id)
    if not order_data:
        return Success(success=0, message="该工单状态不存在")
    datas = await order_detail_flow_by_id(id)
    for data in datas:
        data["doc"] = await get_file_by_record_id("order_details_id", data["id"])
        data["op_time"] = data["op_time"].strftime("%Y-%m-%d %H:%M")
    return SidToOrderResp(data=datas)


async def upload_file_service(req, cid):
    """附件上传"""
    data = await select_cname_by_cid(cid)
    p_name = config.PID_NAME[data["product"]]
    files = req.files.getlist("file")
    qs_url_list = []
    upload_file_name_list = [file.name for file in files]
    if len(upload_file_name_list) != len(set(upload_file_name_list)):
        return SuccessResp(success=0, message="有重复文件，请检查下")
    for file in files:
        file_name = file.name
        file_name_list = file_name.rsplit(".", 1)
        if len(file_name_list) <= 1:
            return SuccessResp(success=0, message="文件格式错误")
        file_name_end = file_name_list[1]
        file_body = file.body
        if file_body and allowed_file(file_name):
            qs_url = f"{DOWNLOAD_ORDER}/{p_name}/{cid}/{uuid4()}.{file_name_end}"
            is_upload = await upload_file(file, qs_url)
            if not is_upload:
                return SuccessResp(success=0, message="上传附件失败")
            await insert_order_files(file_name, qs_url)
            qs_url_list.append(qs_url)
        else:
            return SuccessResp(success=0, message="文件格式不允许")
    fid = []
    if qs_url_list:
        fids = await search_fid_by_url(qs_url_list)
        fid = [f["id"] for f in fids]
    return SuccessResp(success=1, message="操作成功", fid=fid)


async def delete_order_file_service(id):
    """附件删除"""
    file = await get_file_by_id(id)
    if not file:
        return Success(success=0, message=f"删除附件失败id:{id}")
    async with QsClient() as client:
        await client.del_file(key=file["doc_url"])
    # mysql删除
    await delte_order_file(id)
    return SuccessResp(success=1, message="操作成功")


async def download_file_service(id):
    """附件下载"""
    file = await get_file_by_id(id)
    if not file:
        return Success(success=0, message=f"文件不存在或者已删除")
    key = file["doc_url"]
    doc_name = file["doc_name"]
    async with QsClient() as client:
        resp_bytes = await client.get_file(key=key)
    return resp_bytes, doc_name
