import copy
import os.path
import typing

from yangke.common.config import logger
from yangke.ebsilon.graphicsview import YkGraphicsItem, Port
from yangke.ebsilon.constant.constant import Pressure, Temperature, Enthalpy, MassFlow, Power, Length, Area, One, Other, \
    VolumeFlow, SpecificVolume
from yangke.ebsilon.values import Value
from yangke.performance.iapws97 import get_h_by_pt, IAPWS97
from yangke.common.QtImporter import QIcon, QLineF, QPointF, Qt, QPoint, QPainter, QWidget, QStyleOptionGraphicsItem

SpecificationValues = {
    "流体状态参数(总，滞止)": [
        ["参数类型", "FTYP", ["1:压力", "2:温度", "3:焓", "4:质量流量", "5:功率/热流"],  # "6:低位热值", "7:含湿量"],
         None, {"size": [100, 140, 0]}],
        ["测量值", "MEASM", "", {"func": "dynamic_unit(FTYP)"}, ],
        # 这里的func表示单位是根据dynamic_unit()函数确定的，引用的参数必须首先定义，即FTYP必须位于该行之前
    ],
}  # 不能有逗号

Result = {
    "Total": [
        ["雷诺数", "Re", "", One()],
        ["介质运动粘度", "Gamma", "", Other("m^2/s")],
        ["介质动力粘度", "mu", "", Other("Pa·s")],
        ["管道截面积", "A", "", Area("m^2"), "tacit"],
    ]
}


class Item(YkGraphicsItem):
    def __init__(self):
        """

        """
        super(Item, self).__init__()
        self.width = 30
        self.height = 50
        self.EBS_ID = 46  # ebsilon软件中的组件id
        self.NAME = "测量值输入"
        self.EBS_NAME = "Measuring value input"  # ebsilon中的组件名
        self.EBS_TYPE = "Start and Boundary Values"  # ebsilon帮助文件中组件所属的组
        # self.icon = QIcon(os.path.join(os.path.dirname(__file__), "Comp46.PNG"))  # 组件的图标

        # Ebsilon组件面板中的Ports页信息
        self.ports = {
            1: Port(idx=1, point=QPointF(-5, 15), type1="Set Value", description="测量值"),
        }
        self.SpecificationValues = SpecificationValues
        self.Result = Result

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem,
              widget: typing.Optional[QWidget] = ...) -> None:
        """
        绘制组件图形

        :param painter:
        :param option:
        :param widget:
        :return:
        """
        # 绘制组件实体
        self.pen[0].setColor(Qt.black)
        self.pen[0].setWidth(1)
        self.brush[0].setColor(Qt.black)
        self.brush[0].setStyle(Qt.SolidPattern)
        painter.setPen(self.pen[0])
        painter.setBrush(self.brush[0])
        painter.drawLine(QLineF(QPointF(-5, 5), QPointF(-5, -15)))
        painter.drawPolygon([QPoint(-5, -15), QPoint(15, -25), QPoint(15, -5)], Qt.OddEvenFill)  # 三角形

        self.pen[1].setWidth(1)
        self.pen[1].setColor(Qt.red)
        FTYP = self.values.get_values_of_step(symbol="FTYP", step=0)
        if FTYP is None:
            self.pen[1].setColor(Qt.red)
        elif FTYP.startswith("1:"):
            self.pen[1].setColor(Qt.red)
        elif FTYP.startswith("2:"):
            self.pen[1].setColor(Qt.green)
        elif FTYP.startswith("3:"):
            self.pen[1].setColor(Qt.blue)
        elif FTYP.startswith("4:"):
            self.pen[1].setColor(Qt.white)

        self.pen[1].setWidth(4)
        painter.setPen(self.pen[1])
        self.brush[1].setStyle(Qt.NoBrush)
        painter.setBrush(self.brush[1])
        painter.drawPolygon([QPoint(-15, 5), QPoint(5, 5), QPoint(5, 25), QPoint(-15, 25)], Qt.OddEvenFill)

        super(Item, self).paint(painter, option, widget)  # 必须最后调用

    def calculate(self, step=None):
        """
        该组件无需计算，只需将上一个迭代步的值赋值给当前迭代步即可

        :param step:
        :return:
        """
        if step == 0:  # 如果迭代步是0，则说明是初始化过程，组件46的初始化过程参数值由图形界面赋值给self.values，与本方法无关
            ...
        else:
            values = self.values.values_steps.get(step - 1).copy()  # 不同时间步的数据不同
            self.values.set_values(step=step, values=values)
            self.after_values_updated()  # 计算完成后，数据更新需要调用self.after_values_updated()方法完成数据更新后处理
        if self.get("MEASM") is None:
            return f"MEASM 参数未设置！--- break"
        return "done"  # 该组件无需计算，直接返回done表示计算完成

    def spread_values(self, step=None, symbols=None):
        port = self.ports[1]
        _ = copy.deepcopy(self.values)
        if "FTYP" in _.values.keys():
            _.values.pop("FTYP")  # FTYP和MEASM这两个参数不要传给端口，端口只接受P、T、H、M这类通用参数
        if "MEASM" in _.values.keys():
            _.values.pop("MEASM")
        port.values.set_values(step, _)

    def after_values_updated(self):
        """
        当设置该组件的参数后

        :return:
        """
        typ = self.get("FTYP")
        val = self.get("MEASM", need_unit=True)
        if typ is None:
            logger.debug(f"S{self.scene_id}设备的FTYP参数值为{typ}，其values={self.values}")
        elif typ.startswith("1:"):
            self.values.values = {"FTYP": typ, "MEASM": val, "P": val}  # 不能用update，因为update不会把其他参数置为空
        elif typ.startswith("2:"):
            self.values.values = {"FTYP": typ, "MEASM": val, "T": val}
            self.values.update(self.values.values)
        elif typ.startswith("3:"):
            self.values.values = {"FTYP": typ, "MEASM": val, "H": val}
        elif typ.startswith("4:"):
            self.values.values = {"FTYP": typ, "MEASM": val, "M": val}
        elif typ.startswith("5:"):
            self.values.values = {"FTYP": typ, "MEASM": val, "Power": val}

        self.values.update(self.values.values)  # 更新self.values.values_step的数据
        self.scene().update()
