import numpy as np
import copy


class MeterConnector(object):
    """接线判断"""

    def __init__(self, data):
        """ctnum 3:
        data = {'ua':ua, 'ub':ub, 'uc':uc, 'ia':ia, 'ib':ib, 'ic':ic,
                'ctnum':ctnum, 'angleAB':angleAB, 'angleAC':angleAC,
                'phA':phA, 'phB':phB, 'phC':phC}
      ctnum 2:
        data = {'uab':uab, 'ucb':ucb, 'ia':ia, 'ic':ic, 'ctnum':ctnum,
                'angleUabUcb':angleUabUcb, 'phUabIa':phUabIa, 'phUcbIc':phUcbIc}
    """
        self.data = data
        self.derection = True
        self.ui_phasor = None

    def _is_positive_phase_sequence(self):
        if self.data["ctnum"] == 3:
            if self.data["angleAB"] >= 0 and self.data["angleAC"] < 0:
                self.derection = True
            elif self.data["angleAB"] < 0 and self.data["angleAC"] >= 0:
                self.derection = False
            elif self.data["angleAB"] >= 0 and self.data["angleAC"] >= 0 and \
                    self.data["angleAC"] - self.data["angleAB"] < 0:
                self.derection = False
            elif self.data["angleAB"] >= 0 and self.data["angleAC"] >= 0 and \
                    self.data["angleAC"] - self.data["angleAB"] >= 0:
                self.derection = True
            elif self.data["angleAB"] < 0 and self.data["angleAC"] < 0 and \
                    self.data["angleAC"] - self.data["angleAB"] < 0:
                self.derection = False
            elif self.data["angleAB"] < 0 and self.data["angleAC"] < 0 and \
                    self.data["angleAC"] - self.data["angleAB"] >= 0:
                self.derection = True
        else:
            if self.data["angleUabUcb"] < 0:
                self.derection = True
            else:
                self.derection = False

    @staticmethod
    def _pu_UI(data, ctnum):
        """  """
        rst = {}
        k = 1.5
        if ctnum == 3:
            max_U = np.max([data["ua"], data["ub"], data["uc"]])
            max_I = np.max([data["ia"], data["ib"], data["ic"]])
            for u_key in ["ua", "ub", "uc"]:
                rst[u_key] = [k * data[u_key] / (max_U + 0.01), data[u_key]]

            for i_key in ["ia", "ib", "ic"]:
                rst[i_key] = [data[i_key] / (max_I + 0.01), data[i_key]]

        else:
            max_U = np.max([data["uab"], data["ucb"]])
            max_I = np.max([data["ia"], data["ic"]])
            for u_key in ["uab", "ucb"]:
                rst[u_key] = k * data[u_key] / (max_U + 0.01)

            rst['ua'] = [rst['uab'], data["uab"] / 1.732]
            rst['ub'] = [rst['ucb'], data["ucb"] / 1.732]
            rst['uc'] = [0.5 * (rst['uab'] + rst['ucb']),
                         0.5 * (data["uab"] + data["ucb"]) / 1.732]

            for i_key in ["ia", "ic"]:
                rst[i_key] = [data[i_key] / (max_I + 0.01), data[i_key]]
            rst['ib'] = [None, None]
        return rst

    def _phi_cal(self, data, ctnum):
        """ phi_uabc:[angleAB, angleAC] or [angleUabUcb]
       phi_iabc:[phA, phB, phC] or [phUabIa, phUcbIc] """
        phi = {}
        if not self.derection:
            delt_phi = -30
        else:
            delt_phi = 30
        if ctnum == 3:
            phi['ua'] = 0
            phi['ub'] = -data["angleAB"]
            phi['uc'] = -data["angleAC"]
            phi['uab'] = phi['ua'] + delt_phi
            phi['ucb'] = phi['uc'] - delt_phi

            phi['ia'] = -data["phA"]
            phi['ib'] = phi['ub'] - data["phB"]
            phi['ic'] = phi['uc'] - data["phC"]
        else:
            if data["angleUabUcb"] > 0:
                ph_uab_init = -30
            else:
                ph_uab_init = 30
            phi['uab'] = ph_uab_init
            phi['ucb'] = phi['uab'] - data["angleUabUcb"]

            phi['ia'] = phi['uab'] - data["phUabIa"]
            phi['ib'] = None
            phi['ic'] = phi['ucb'] - data["phUcbIc"]

            phi['ua'] = phi['uab'] - delt_phi
            phi['ub'] = phi['ua'] - delt_phi * 4
            phi['uc'] = phi['ucb'] + delt_phi

        return phi

    @staticmethod
    def _format_convert(r, phi, ctnum):
        u = {}
        r_copy = copy.deepcopy(r)
        phi_copy = copy.deepcopy(phi)
        for item in ["ua", "ub", "uc", "ia", "ib", "ic"]:
            u[item] = r_copy[item] + [phi_copy[item]]
        return u

    def output(self):
        self._is_positive_phase_sequence()
        r_uiabc = self._pu_UI(self.data,
                              self.data['ctnum'])
        phi_uiabc = self._phi_cal(self.data,
                                  self.data['ctnum'])
        # self.ui_phasor = self._format_convert(r_uiabc,
        #                                       phi_uiabc,
        #                                       self.data['ctnum'])
        return self._format_convert(r_uiabc, phi_uiabc, self.data['ctnum'])


def meter_result(electrics):
    """调用算法，得到ia ib ic ua ub uc"""
    ctnum = electrics.get("ctnum")
    if ctnum == 2:
        angleUabUcb = electrics.get("angleUabUcb")
        ia = electrics.get("ia")
        ic = electrics.get("ic")
        phUabIa = electrics.get("phUabIa")
        phUcbIc = electrics.get("phUcbIc")
        uab = electrics.get("uab")
        ucb = electrics.get("ucb")
        data = {'ctnum': 2, 'angleUabUcb': angleUabUcb, 'ia': ia, 'ic': ic,
                'phUabIa': phUabIa, 'phUcbIc': phUcbIc, 'uab': uab,
                'ucb': ucb}
    else:
        ua = electrics.get("ua")
        ub = electrics.get("ub")
        uc = electrics.get("uc")
        ia = electrics.get("ia")
        ib = electrics.get("ib")
        ic = electrics.get("ic")
        angleAB = electrics.get("angleAB")
        angleAC = electrics.get("angleAC")
        phA = electrics.get("phA")
        phB = electrics.get("phB")
        phC = electrics.get("phC")
        data = {'ctnum': 3, 'ua': ua, 'ub': ub, 'uc': uc, 'ia': ia,
                'ib': ib, 'ic': ic, 'angleAB': angleAB, 'angleAC': angleAC,
                'phA': phA, 'phB': phB, 'phC': phC}
    # 调用算法接口
    mc = MeterConnector(data)
    return mc.output()


if __name__ == "__main__":
    # data = {'ctnum': 2, 'angleUabUcb': -60, 'ia': 0.896, 'ic': 0.896,
    #         'phUabIa': 29.799, 'phUcbIc': -32.4, 'uab': 103.79, 'ucb': 103.42}
    # data = {'ctnum': 2, 'angleUabUcb': -60, 'ia': 0.896, 'ic': 0.896,
    #         'phUabIa': 50.799, 'phUcbIc': -9.4, 'uab': 103.79, 'ucb': 103.42}
    # data = {'ctnum': 2, 'angleUabUcb': 60, 'ia': 3.009, 'ic': 3.071,
    #         'phUabIa': 4.7, 'phUcbIc': 62.5, 'uab': 103.79, 'ucb': 103.42}
    data = {'ctnum': 3, 'ua': 60, 'ub': 60, 'uc': 60, 'ia': 1.707, 'ib': 1.35,
            'ic': 1.53, 'angleAB': 120, 'angleAC': -120, 'phA': 33.09,
            'phB': 28.9, 'phC': 37}
    data = {'ctnum': 3, 'ua': 60, 'ub': 60, 'uc': 60, 'ia': 2.27, 'ib': 2.23,
            'ic': 2.35, 'angleAB': -120, 'angleAC': 120, 'phA': 11.9,
            'phB': 10.08, 'phC': 12.1}
    data1 = MeterConnector(data)
    # print(data1.ui_phasor)
