import os

import pandas as pd
import plotly.graph_objects as go
from algorithmContract.confBusiness import *
from algorithmContract.contract import Contract
from behavior.analystWithGoodBadPoint import AnalystWithGoodBadPoint


class PowerScatterAnalyst(AnalystWithGoodBadPoint):
    """
    风电机组功率曲线散点分析。
    秒级scada数据运算太慢，建议使用分钟级scada数据
    """

    def typeAnalyst(self):
        return "power_scatter"

    def selectColumns(self):
        return [Field_DeviceCode, Field_Time, Field_WindSpeed, Field_ActiverPower]

    def processDateTime(self, dataFrame: pd.DataFrame, fieldTime:str = None):
        super().processDateTime(dataFrame,Field_YearMonth)

    def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes):
        dictionary = self.processTurbineData(turbineCodes, conf, self.selectColumns())
        dataFrame = self.userDataFrame(dictionary, conf.dataContract.configAnalysis, self)
        if len(dataFrame) <= 0:
            print("After screening for blade pitch angle less than the configured value, plot power curve scatter points without data")
            return

        # dataFrameGuaranteePowerCurve=self.powerFarmInfo[Field_PowerContractURL]
        # grouped=self.dataFrameContractOfTurbine.groupby([Field_PowerFarmCode, Field_MillTypeCode])

        # for groupByKey,contractPowerCurveOfMillType in grouped:
        #     break
        turbineInfos = self.common.getTurbineInfos(conf.dataContract.dataFilter.powerFarmID, turbineCodes, self.turbineInfo)
        return self.drawOfPowerCurveScatter(dataFrame,turbineInfos, outputAnalysisDir, conf)

    """
    def contractGuaranteePowerCurveData(self, csvPowerCurveFilePath):
        dataFrameGuaranteePowerCurve = pd.read_csv(
            csvPowerCurveFilePath, encoding=charset_unify)

        return dataFrameGuaranteePowerCurve
    """
    def drawOfPowerCurveScatter(self, dataFrame: pd.DataFrame,  turbineModelInfo: pd.Series, outputAnalysisDir, conf: Contract):
        """
        绘制风速-功率分布图并保存为文件。

        参数:
        dataFrameMerge (pd.DataFrame): 包含数据的DataFrame，需要包含设备名、风速和功率列。
        csvPowerCurveFilePath (str): 功率曲线文件路径。
        outputAnalysisDir (str): 分析输出目录。
        conf (ConfBusiness): 配置
        """

        colorsList = [  
                        "#3E409C",
                        "#3586BF",
                        "#52A3AE",
                        "#85D0AE",
                        "#A8DCA2",
                        "#FBFFBE",
                        "#FDF1A9",
                        "#FFE286",
                        "#FCB06C",
                        "#F96F4A",
                        "#E4574C",
                        "#AF254F"]
        cutInWsField = self.turbineModelInfo[Field_CutInWS]
        cut_in_ws = cutInWsField.min() - 1 if cutInWsField.notna().any() else 2
        # if not dataFrame.empty and Field_CutInWS in  dataFrame.columns and  dataFrame[Field_CutInWS].notna().any():
        #     cut_in_ws =  dataFrame[Field_CutInWS].min() - 1
        # else:
        #     cut_in_ws = 2

        grouped = dataFrame.groupby([Field_NameOfTurbine, Field_CodeOfTurbine])

        result_rows = []
        # 遍历每个设备的数据
        for name, group in grouped:
            # 创建颜色映射，将每个年月映射到一个唯一的颜色
            unique_months = group[Field_YearMonth].unique()
            colors = [
                colorsList[i % 12] for i in range(len(unique_months))]
            color_map = dict(zip(unique_months, colors))

            # 使用go.Scatter3d创建3D散点图
            trace = go.Scatter3d(
                x=group[Field_WindSpeed],
                y=group[Field_YearMonth],
                z=group[Field_ActiverPower],
                mode='markers',
                marker=dict(
                    color=[color_map[month]
                           for month in group[Field_YearMonth]],
                    size=1.5,
                    line=dict(
                        color='rgba(0, 0, 0, 0)',  # 设置边框颜色为透明，以去掉白色边框
                        width=0  # 设置边框宽度为0，进一步确保没有边框
                    ),
                    opacity=0.8  # 调整散点的透明度，增加透视效果
                )
            )

            # 创建图形
            fig = go.Figure(data=[trace])

            # 更新图形的布局
            fig.update_layout(
                title={
                    "text": f'逐月有功功率散点3D分析: {name[0]}',
                    "x": 0.5
                },
                scene=dict(
                    xaxis=dict(
                        title='风速',
                        range=[cut_in_ws, 25],
                    ),
                    yaxis=dict(
                        title='时间',
                        tickmode='array',
                        tickvals=unique_months,
                        ticktext=unique_months,
                        categoryorder='category ascending'
                    ),
                    zaxis=dict(
                        title='功率',
                        range=[self.axisLowerLimitActivePower, self.axisUpperLimitActivePower],
                        dtick=self.axisStepActivePower,
                    )
                ),
                scene_camera=dict(
                    up=dict(x=0, y=0, z=1),  # 保持相机向上方向不变
                    center=dict(x=0, y=0, z=0),  # 保持相机中心位置不变
                    eye=dict(x=-1.8, y=-1.8, z=1.2)  # 调整eye属性以实现水平旋转180°
                ),
                margin=dict(t=50, b=10)  # t为顶部（top）间距，b为底部（bottom）间距
            )

            # 确保从 Series 中提取的是具体的值
            engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "")
            if isinstance(engineTypeCode, pd.Series):
                engineTypeCode = engineTypeCode.iloc[0]

            engineTypeName = turbineModelInfo.get(Field_MachineTypeCode, "")
            if isinstance(engineTypeName, pd.Series):
                engineTypeName = engineTypeName.iloc[0]
            # 构建最终的JSON对象
            json_output = {
                "analysisTypeCode": "逐月有功功率散点3D分析",
                "engineCode":  engineTypeCode,    
                "engineTypeName": engineTypeName, 
                "xaixs": "风速（m/s）",
                "yaixs": "时间",
                "zaixs": "有功功率（kW)",
                "data": [{
                        "engineName": name[0],
                        "engineCode": name[1],
                        "title":f'逐月有功功率散点3D分析-机组: {name[0]}',
                        "xData": group[Field_WindSpeed].tolist(),
                        "xrange":[cut_in_ws, 25],
                        "yData":group[Field_YearMonth].tolist(),
                        "zData":group[Field_ActiverPower].tolist(),
                        "zrange":[self.axisLowerLimitActivePower, self.axisUpperLimitActivePower],
                        "color":group[Field_YearMonth].tolist()
                        }]
            }
            # # Save plot
            # filePathOfHtml = os.path.join(outputAnalysisDir, f"{name[0]}.html")
            # fig.write_html(filePathOfHtml)
            # 将JSON对象保存到文件
            output_json_path = os.path.join(outputAnalysisDir, f"power_scatter{name[0]}.json")
            with open(output_json_path, 'w', encoding='utf-8') as f:
                import json
                json.dump(json_output, f, ensure_ascii=False, indent=4)

            # 如果需要返回DataFrame，可以包含文件路径
            result_rows.append({
                Field_Return_TypeAnalyst: self.typeAnalyst(),
                Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
                Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
                Field_CodeOfTurbine: name[1],
                Field_Return_FilePath: output_json_path,
                Field_Return_IsSaveDatabase: True
            })
            # result_rows.append({
            #     Field_Return_TypeAnalyst: self.typeAnalyst(),
            #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
            #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
            #     Field_CodeOfTurbine: name[1],
            #     Field_Return_FilePath: filePathOfHtml,
            #     Field_Return_IsSaveDatabase: True
            # })

        result_df = pd.DataFrame(result_rows)

        return result_df
