# -*- coding:utf-8 -*-
#
# Author:jing
# Date: 2020/6/1
import typing
from dataclasses import dataclass

from pot_libs.common.components.fields import Sid
from pot_libs.sanic_api.column import List, DateTime, Int, Float, Str, Dict
from pot_libs.sanic_api.http_status import bad_request
from pot_libs.sanic_api.model import Model
from unify_api.utils.response_code import UserErr


def normalize(degree):
    return ((degree % 360) + 360) % 360


def delta(degree1, degree2):
    normal_degree1 = normalize(degree1)
    normal_degree2 = normalize(degree2)
    diff = abs(normal_degree1 - normal_degree2)
    if diff > 180:
        diff = 360 - diff
    return diff


class Result(typing.NamedTuple):
    result: tuple
    degree: int
    degrees: tuple


@dataclass
class DebugRequest(Model):
    sid: str = Sid
    meter_sn: str = Str()


@dataclass
class DebugValueElectric(Model):
    """电气量数据,三表法和两表法不同。"""
    ua: float = Float()
    ub: float = Float()
    uc: float = Float()
    uab: float = Float()
    ucb: float = Float()
    ia: float = Float()
    ib: float = Float()
    ic: float = Float()
    cosa: float = Float()
    cosb: float = Float()
    cosc: float = Float()
    costtl: float = Float()
    pa: float = Float()
    pb: float = Float()
    pc: float = Float()
    pttl: float = Float()

    phA: float = Float()
    phB: float = Float()
    phC: float = Float()
    phUabIa: float = Float()
    phUcbIc: float = Float()

    angleAB: float = Float()
    angleAC: float = Float()
    angleUabUcb: float = Float()

    qa: float = Float()
    qb: float = Float()
    qc: float = Float()
    qttl: float = Float()

    ctnum: int = Int()


@dataclass
class DebugValueAdio(Model):
    """adio数据"""

    def __init__(self, adio):
        self.adio = adio

    def to_dict(self, *, fix=None):
        return self._value_to_dict(self.adio, fix)

    @classmethod
    def from_dict(cls, data):
        return cls(data)

    @classmethod
    def example(cls):
        return dict(temp1=27, temp2=23, di0=0, di1=2)


@dataclass
class DebugValue(Model):
    """"""
    electric: DebugValueElectric
    adio: DebugValueAdio
    date_time: str = DateTime("电气量的时间,界面以这个时间为主")
    adio_date: str = DateTime("adio量的时间")


@dataclass
class Conclusion(Model):
    """接线结论: 在角度为[left, right]时,结论为result, 最佳点opt_degree"""
    result: tuple = List(
        'ABC对应的结果,负号表示反向'
    ).items(Str()).eg(['B', '-A', 'C'])
    opt_degree: int = Int("局部最优可能性的角度点")
    opt_degrees: tuple = List().items(Int())
    left: float = Int()
    right: float = Int()

    def cmp(self, degrees):
        if sum(degrees) < sum(self.opt_degrees):
            return True
        elif sum(degrees) > sum(self.opt_degrees):
            return False
        else:
            def _(degree_list):
                product = 1
                for d in degree_list:
                    product *= normalize(d)
                return product

            return _(degrees) < _(self.opt_degrees)

    def check(self, result: Result):
        self.right = result.degree
        if self.cmp(result.degrees):
            self.opt_degrees = result.degrees
            self.opt_degree = result.degree


@dataclass
class DebugResponse(Model, UserErr):
    """返回接线情况,按照顺序为ABC,或AC。"""
    # conclusions: list = List().items(Conclusion)
    values: typing.List[DebugValue] = List('最近几次数据').items(DebugValue)
    conclusions: dict = Dict().eg({'ua': [1.4997500416597234, 60, 0],
                                   'ub': [1.4997500416597234, 60, 120],
                                   'uc': [1.4997500416597234, 60, -120],
                                   'ia': [0.9618644067796611, 2.27, -11.9],
                                   'ib': [0.9449152542372882, 2.23, 109.92],
                                   'ic': [0.9957627118644069, 2.35, -132.1]})

    @classmethod
    @bad_request
    def sid_data_missing(cls, sid):
        """sid最近没有电气量数据"""
        return f'sid {sid} data missing'

    @classmethod
    @bad_request
    def sid_exits(cls, sid):
        """装置已安装"""
        return f'sid {sid} exits'


@dataclass
class AssiResponse(Model, UserErr):
    ua: list = List().eg([1.4997500416597234, 60, 0])
    ub: list = List().eg([1.4997500416597234, 60, 120])
    uc: list = List().eg([1.4997500416597234, 60, -120])
    ia: list = List().eg([0.9618644067796611, 2.27, -11.9])
    ib: list = List().eg([0.9449152542372882, 2.23, 109.92])
    ic: list = List().eg([0.9957627118644069, 2.35, -132.1])

    @classmethod
    @bad_request
    def sid_exits(cls, sid):
        """装置已安装"""
        return f'sid {sid} exits'

    @classmethod
    @bad_request
    def sid_data_missing(cls, sid):
        """sid最近没有电气量数据"""
        return f'sid {sid} data missing'


if __name__ == '__main__':
    print(DebugValue.get_schema())