# -*- coding: utf-8 -*-
# @Time : 2022/5/30 14:45
# @Author : Opfer
# @Site :
# @File : dispatchInfo.py
# @Software: PyCharm
import numpy as np

from settings import *
import pandas as pd

logger = get_logger("mqc.dispatchInfo")


class DispatchInfo:
    """
    class for dispatch group info.
    """

    # dispatch groups
    group_set = set()

    # device group structure
    group_dump_dict = {}  # team_id -> dict {unload_area_id, unload_area_id, ...}
    group_excavator_dict = {}  # team_id -> dict {[excavator_id, excavator_id], ...}
    load_exactor_dict = {}  # 装载区id-->>电铲编号的映射
    exactor_load_dict = {}  # 电铲编号->>装载区id的映射
    group_truck_dict = {}  # team_id -> dict # {group_id:[truck_id,truck_id],...}
    dump_group_dict = {}  # unload_area_id -> team_id
    excavator_group_dict = {}  # excavator_id -> team_id   问题：多个key值对应一个value值
    truck_group_dict = {}  # truck_id -> team_id

    # group feature
    group_mode = {}  # 数据格式： {team_id:mode_code}

    # route_distance（路网距离）
    load_distance = {}  # 装载区-挖机（电铲）的距离  数据格式 -->>{team_id:np.array}
    unload_distance = {}  # 卸载区-挖机（电铲）的距离 数据格式 -->>{team_id:np.array}

    @classmethod
    def renew_set(cls):
        """
        @date：2022/6/2 19:50
        @author：maqc
        @desc：实例化对象，可直接访问
        """

        cls.group_dump_dict = {}   # cls.group_dump_dict.keys() 相当于所有的team_id
        cls.dump_group_dict = {}  # cls.dump_group_dict.keys() 相当于所有的卸载区 unload_area_id
        cls.group_excavator_dict = {}
        cls.excavator_group_dict = {}
        cls.load_exactor_dict = {}  # cls.load_exactor_dict.keys() 相当于所有的装载区 load_area_id
        cls.exactor_load_dict = {}
        cls.group_truck_dict = {}
        cls.truck_group_dict = {}
        cls.group_mode = {}
        cls.load_distance = {}  # to_load_diatance-->>空车模式
        cls.unload_distance = {}  # to_unload_distance-->>重车模式

    @classmethod
    def update_device_group_structure(cls):
        """
        @date：2022/6/2 19:49
        @author：maqc
        @desc：分组与卸载区、挖机、矿卡的映射和反映射
        """
        logger = get_logger("mqc.update_device_group_structure")
        try:
            # group_dump_dict = {} -->> {team_id:[unload_area_id,unload_area_id],...}
            # dump_group_dict = {}  # unload_area_id -> team_id
            group_code_dict = {}  # group_code-->>team_id的映射
            for valve in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
                group_code_dict[valve.group_code] = valve.team_id
                if valve.team_id not in cls.group_dump_dict:
                    cls.group_dump_dict[valve.team_id] = [valve.unload_area_id]  # 注意：一个team_id可能对应多个unload_area_id
                else:
                    cls.group_dump_dict[valve.team_id].append(valve.unload_area_id)
                    cls.dump_group_dict[valve.unload_area_id] = valve.team_id  # 一个unload_area_id只对应一个team_id
            # group_excavator_dict = {} -->>  {team_id: [excavator_id, excavator_id], ...}  # 一个team_id对应一组excavator_id, unload_area_id
            # excavator_group_dict = {} -->>  excavator_id -> team_id  一个excavator_id只对应一个team_id
            for item in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
                if item.team_id in cls.group_excavator_dict:
                    cls.group_excavator_dict[item.team_id].append(item.exactor_id)
                else:
                    cls.group_excavator_dict[item.team_id] = [item.exactor_id]
                cls.excavator_group_dict[item.exactor_id] = item.team_id
            # group_truck_dict = {} -->> {team_id:[truck_id,truck_id],...}
            # truck_group_dict = {} -->> truck_id -> team_id
            for key in session_mysql.query(DispatchEquipment).filter_by(group_type=1).all():
                if key.group_code in group_code_dict:
                    if key.group_code not in cls.group_truck_dict:
                        cls.group_truck_dict[key.group_code] = [key.equipment_id]
                    else:
                        cls.group_truck_dict[key.group_code].append(key.equipment_id)
                    cls.truck_group_dict[key.equipment_id] = group_code_dict[key.group_code]
        except Exception as es:
            logger.error("分组到卸载区的数据更新异常")
            logger.error(es)

    @classmethod
    def update_group_mode(cls):
        """
        @date：2022/6/2 19:49
        @author：maqc
        @desc：处理其它类型的数据
        """
        # 新增：team_id-->>group_code;group_code-->>mode_code.结果：team_id-->>mode_code
        logger = get_logger("mqc.update_group_mode")
        team_group_dict = {}  # team_id-->>group_code的一个映射，格式：{team_id:group_code}
        group_mode_dict = {}  # group-->>mode_code的一个映射，格式：{group_code:mode_code}
        try:
            for pos in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
                team_group_dict[pos.team_id] = pos.group_code
            for item in session_mysql.query(DispatchGroup).filter_by(group_type=1).all():
                group_mode_dict[item.group_code] = item.mode_code
            for key, value in team_group_dict.items():
                if value in group_mode_dict:
                    cls.group_mode[key] = group_mode_dict[value]
        except Exception as es:
            logger.error("派车模式数据更新异常")
            logger.error(es)

    @classmethod
    def dispatch_group_init(cls):
        """
        update basic paras (group_set, dict, num ...)
        :return:
        """
        try:
            for value in session_postgre.query(DiggingWorkArea).all():
                cls.load_exactor_dict[value.Id] = value.ExactorId
                cls.exactor_load_dict[value.ExactorId] = value.Id
        except Exception as es:
            logger.error("初始化数据更新异常")
            logger.error(es)

    @classmethod
    # 距离-->>数据格式：矩阵-->>to_load_distance
    def update_route_distance(cls):
        """
        @date：2022/6/2 19:50
        @author：maqc
        @desc：更新路网距离，返回矩阵格式数据
        """
        logger = get_logger("mqc.update_route_distance")
        try:
            df = pd.DataFrame()  # 记录装载区与卸载区之间的距离
            for item in session_postgre.query(WalkTime).all():
                temp = str(item.load_area_id), str(item.unload_area_id), item.to_load_distance, item.to_unload_distance
                df = pd.concat([df, pd.DataFrame([temp])], axis=0, ignore_index=True)

            for team_id in list(cls.group_dump_dict.keys()):
                unload_nums = list(set(cls.group_dump_dict[team_id]))  # 获取同一个team_id对应的卸载区列表
                exactor_nums = list(set(cls.group_excavator_dict[team_id]))  # 获取同一个team_id对应的电铲列表

                unload_exactor_matrix = np.zeros(
                    (len(unload_nums), len(exactor_nums)))  # 初始化距离矩阵，记录从卸载区-->>电铲的距离，即to_load_distance，空车模式
                load_exactor_matrix = np.array(
                    unload_exactor_matrix).T  # 初始化距离矩阵，记录从装载区-->>电铲的距离，即to_unload_distance，重车模式
                for i in range(len(unload_nums)):
                    for j in range(len(exactor_nums)):
                        id = set(df.loc[df[1] == str(unload_nums[i])].index.to_list()) & set(
                            df.loc[df[0] == str(cls.exactor_load_dict[j])].index.to_list())  # 集合属性
                        unload_exactor_matrix[i][j] = df.iloc[list(id)[0]][2]
                for m in range(len(exactor_nums)):
                    for n in range(len(unload_nums)):
                        id = set(df.loc[df[0] == str(cls.exactor_load_dict[m])].index.to_list()) & set(
                            df.loc[df[1] == str(unload_nums[n])].index.to_list())
                        load_exactor_matrix[m][n] = df.iloc[list(id)[0]][3]
                cls.load_distance[team_id] = unload_exactor_matrix
                cls.unload_distance[team_id] = load_exactor_matrix
        except Exception as es:
            logger.error("路网数据更新异常")
            logger.error(es)

    @classmethod
    def get_group_mode(cls, group_id):
        return cls.group_mode[group_id]

    @classmethod
    def get_excavator_dict(cls, group_id):
        return cls.group_excavator_dict[group_id]

    @classmethod
    def get_dump_dict(cls, group_id):
        return cls.group_dump_dict[group_id]

    @classmethod
    def get_truck_set(cls, group_id):
        return cls.group_truck_dict[group_id]

    @classmethod
    def get_to_excavator_distance(cls, group_id):
        return cls.load_distance[group_id]

    @classmethod
    def get_to_dump_distance(cls, group_id):
        return cls.unload_distance[group_id]

    @classmethod
    def get_park_to_excavator_distance(cls, group_id):
        return cls.park_distance[group_id]

    @classmethod
    def get_park_to_excavator_distance(cls, group_id):
        excavators = cls.group_excavator_dict[group_id]
        park_matrix = np.zeros((1, len(excavators)))
        for i in range(excavators):
            load_area_id = cls.exactor_load_dict[excavators[i]]
            distance = session_postgre.query(WalkTimePark).filter_by(load_area_id=load_area_id).first()
            park_matrix[0][i] = distance
        return park_matrix

# #!E:\Pycharm Projects\Waytous
# # -*- coding: utf-8 -*-
# # @Time : 2022/5/30 14:45
# # @Author : Opfer
# # @Site :
# # @File : dispatchInfo.py
# # @Software: PyCharm
# from settings import *
#
# logger = get_logger("mqc.dispatchInfo")
#
#
# class DispatchInfo:
#     """
#     class for dispatch group info.
#     """
#
#     # dispatch groups
#     group_set = set()
#
#     # device group structure
#     group_dump_dict = {}  # team_id -> dict {unload_area_id, unload_area_id, ...}
#     # {group_id:unload_area_id,...}
#     group_excavator_dict = {}  # team_id -> dict {[excavator_id, load_area_id], ...}
#     # {group_id: [excavator_id, unload_area_id], ...}
#     group_truck_dict = {}  # team_id -> dict {truck_id, ...}
#     # {group_id:[truck_id,truck_id],...}
#
#     dump_group_dict = {}  # unload_area_id -> team_id
#     excavator_group_dict = {}  # excavator_id -> team_id
#     truck_group_dict = {}  # truck_id -> team_id
#
#     # group feature
#     group_mode = {}  # 四种模式：全智能、空车智能、定铲定铲和分流配比模式
#     # {mode_name:mode_code}
#
#     # route_distance（路网距离）
#     load_excavator_distance = {}  # 装载区-挖机（电铲）的距离  数据格式 -->> {load_area_id:[excavator_uuid, to_load_distance],}
#     unload_excavator_distance = {}  # 卸载区-挖机（电铲）的距离 数据格式 -->> {unload_area_id:[excavator_uuid, to_unload_distance],}
#
#     @classmethod
#     def renew_set(cls):
#         """
#         @date：2022/6/2 19:50
#         @author：maqc
#         @desc：实例化对象，可直接访问
#         """
#         cls.group_dump_dict = {}
#         cls.dump_group_dict = {}
#
#         cls.group_excavator_dict = {}
#         cls.excavator_group_dict = {}
#
#         cls.group_truck_dict = {}
#         cls.truck_group_dict = {}
#
#         cls.group_mode = {}
#         cls.load_excavator_distance = {}
#         cls.unload_excavator_distance = {}
#
#     @classmethod
#     def update_device_group_structure(cls):
#         """
#         @date：2022/6/2 19:49
#         @author：maqc
#         @desc：分组与卸载区、挖机、矿卡的映射和反映射
#         """
#         logger = get_logger("mqc.update_device_group_structure")
#         try:
#             # group_dump_dict = {} -->> {group_id:unload_area_id,...}
#             # dump_group_dict = {}  # unload_area_id -> team_id
#             group_code_dict = {}  # group_code-->>team_id的映射
#             for valve in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
#                 group_code_dict[valve.group_code] = valve.team_id
#                 if valve.team_id not in cls.group_dump_dict:
#                     cls.group_dump_dict[valve.team_id] = [valve.unload_area_id]  # 注意：一个team_id可能对应多个unload_area_id
#                 else:
#                     cls.group_dump_dict[valve.team_id].append(valve.unload_area_id)
#                     cls.dump_group_dict[valve.unload_area_id] = valve.team_id  # 一个unload_area_id只对应一个team_id
#             # group_excavator_dict = {} -->>  {group_id: [excavator_id, unload_area_id], ...}  # 一个team_id对应一组excavator_id, unload_area_id
#             # excavator_group_dict = {} -->>  excavator_id -> team_id  一个excavator_id只对应一个team_id
#             for item in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
#                 # cls.group_excavator_dict[item.team_id] = [item.exactor_id, item.unload_area_id]
#                 cls.group_excavator_dict[item.team_id] = item.exactor_id
#                 cls.excavator_group_dict[item.exactor_id] = item.team_id
#             # group_truck_dict = {} -->> {group_id:[truck_id,truck_id],...}
#             # truck_group_dict = {} -->> truck_id -> team_id
#             for key in session_mysql.query(DispatchEquipment).filter_by(group_type=1).all():
#                 if key.group_code in group_code_dict:
#                     if key.group_code not in cls.group_truck_dict:
#                         cls.group_truck_dict[key.group_code] = [key.equipment_id]
#                     else:
#                         cls.group_truck_dict[key.group_code].append(key.equipment_id)
#                     cls.truck_group_dict[key.equipment_id] = group_code_dict[key.group_code]
#         except Exception as es:
#             logger.error("分组到卸载区的数据更新异常")
#             logger.error(es)
#
#     @classmethod
#     def update_group_mode(cls):
#         """
#         @date：2022/6/2 19:49
#         @author：maqc
#         @desc：处理其它类型的数据
#         """
#         logger = get_logger("mqc.update_group_mode")
#         try:
#             for value in session_mysql.query(DispatchMode).all():
#                 cls.group_mode[value.mode_name] = value.mode_code
#         except Exception as es:
#             logger.error("派车模式数据更新异常")
#             logger.error(es)
#
#     @classmethod
#     def dispatch_group_init(cls):
#         """
#         update basic paras (group_set, dict, num ...)
#         :return:
#         """
#         pass
#
#
#     @classmethod
#     def get_group_road_info(cls,group_id, truck_info):
#         if truck_info == 1:
#             for i in group_excavator():
#                 pass
#                 for j in group_dump():
#                     pass
#         if truck_info == 2:
#             pass
#     @classmethod
#     # 距离-->>数据格式：矩阵-->>to_load_distance
#     def update_route_distance(cls):
#         """
#         @date：2022/6/2 19:50
#         @author：maqc
#         @desc：更新路网距离，返回矩阵格式数据
#         """
#         load_exactor_dict = {}  # 装载区id-->>电铲编号的映射
#         logger = get_logger("mqc.update_route_distance")
#         try:
#             for value in session_postgre.query(DiggingWorkArea).all():
#                 load_exactor_dict[value.Id] = value.Exactorld
#             for value in session_postgre.query(WalkTime).all():
#                 if value.load_area_id in load_exactor_dict:
#                     cls.load_excavator_distance[value.load_area_id] = [load_exactor_dict[value.load_area_id],
#                                                                        value.to_load_distance]
#                     cls.unload_excavator_distance[value.unload_area_id] = [load_exactor_dict[value.load_area_id],
#                                                                            value.to_unload_distance]
#         except Exception as es:
#             logger.error("路网数据更新异常")
#             logger.error(es)
#
#



