from PySide6.QtGui import QIntValidator, QDoubleValidator
from matplotlib.ticker import FuncFormatter


class Filename:
    # 文件命名
    PATH_ORGBCG_TEXT: str = "OrgBCG_Text"
    PATH_PSG_TEXT: str = "PSG_Text"
    PATH_ORGBCG_ALIGNED: str = "OrgBCG_Aligned"
    PATH_PSG_ALIGNED: str = "PSG_Aligned"
    PATH_ORGBCG_ORIGIN: str = "OrgBCG_Origin"
    PATH_PSG_ORIGIN: str = "PSG_Origin"
    PATH_LABEL: str = "Label"
    PATH_REVEIVE_ORIGIN: str = "Receive_Origin"
    PATH_REPORT: str = "Report"
    PATH_SAMPID: str = "<sampID>"
    SUFFIX_FREQ: str = "采样率"

    # Folder: OrgBCG_Text
    ORGBCG_RAW: str = "OrgBCG_Raw_"
    BCG_FILTER: str = "BCG_Filter_"
    JPEAK_REVISE: str = "Jpeak_revise_"
    JPEAK_REVISE_CORRECTED: str = "Jpeak_revise_corrected_"

    # Folder: PSG_Text
    ECG_RAW: str = "ECG II_Raw_"
    THO_RAW: str = "Effort Tho_Raw_"
    ABD_RAW: str = "Effort Abd_Raw_"
    FLOWT_RAW: str = "Flow T_Raw_"
    FLOWP_RAW: str = "Flow P_Raw_"
    SNORE_RAW: str = "Snore_Raw_"
    SPO2_RAW: str = "SpO2_Raw_"
    FIVE_CLASS_RAW: str = "5_class_Raw_"
    STARTTIME_RAW: str = "StartTime_Raw"
    SA_LABEL_RAW: str = "SA Label_Raw"
    ECG_FILTER: str = "ECG_Filter_"
    RPEAK_FINAL: str = "Rpeak_final_"
    RPEAK_FINAL_CORRECTED: str = "Rpeak_final_corrected_"

    # Folder: OrgBCG_Aligned
    ORGBCG_SYNC: str = "OrgBCG_Sync_"
    BCG_SYNC: str = "BCG_Sync_"

    # Folder: PSG_Aligned
    STAGE_SYNC: str = "5_class_Sync_"
    ECG_SYNC: str = "ECG_Sync_"
    THO_SYNC: str = "Effort Tho_Sync_"
    ABD_SYNC: str = "Effort Abd_Sync_"
    FLOWT_SYNC: str = "Flow T_Sync_"
    FLOWP_SYNC: str = "Flow P_Sync_"
    SNORE_SYNC: str = "Snore_Sync_"
    SPO2_SYNC: str = "SpO2_Sync_"
    FIVE_CLASS_SYNC: str = "5_class_Sync_"
    SA_LABEL_SYNC: str = "SA Label_Sync"
    JPEAK_SYNC: str = "Jpeak_Sync_"
    RPEAK_SYNC: str = "Rpeak_Sync_"

    # Folder: Label
    APPROXIMATELY_ALIGN_INFO: str = "Approximately_Align_Info"
    PRECISELY_ALIGN_INFO: str = "Precisely_Align_Info"
    ARTIFACT_A: str = "Artifact_a_"
    ARTIFACT_B: str = "Artifact_b_"
    ARTIFACT_C: str = "Artifact_c_"
    SA_LABEL_CORRECTED: str = "SA Label_corrected"
    SA_LABEL_ADD: str = "SA Label_add"
    RESP_QUALITY_LABEL: str = "Resp_quality_label"
    THO_PEAK: str = "Tho_peak_"
    SQ_LABEL_10S: str = "SQ_label_10s"
    SQ_LABEL_30S: str = "SQ_label_30s"


class Params:

    # 公共
    PUBLIC_CONFIG_FILE_PATH: str = "./config/Config_public.yaml"
    PUBLIC_CONFIG_NEW_CONTENT = {
        "Path": {
            "Root": ""
        }
    }
    UTF8_ENCODING: str = "utf-8"
    GBK_ENCODING: str = "gbk"
    ENDSWITH_TXT: str = ".txt"
    ENDSWITH_CSV: str = ".csv"
    ENDSWITH_EDF: str = ".edf"
    FORMATTER = FuncFormatter(lambda x, p: f"{x:.0f}")
    ACTION_PAN_SHORTCUT_KEY: str = "X"
    ACTION_ZOOM_SHORTCUT_KEY: str = "C"
    FONT: str = "Microsoft YaHei UI"
    VALIDATOR_INTEGER = QIntValidator(-2**31, 2**31 - 1)
    VALIDATOR_DOUBLE = QDoubleValidator(-1e100, 1e100, 10)

    # 数据粗同步
    APPROXIMATELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_approximately_align.yaml"
    APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "orgBcgFreq": 1000,
            "ThoFreq": 100,
            "AbdFreq": 100
        },
        "ApplyFrequency": 5,
        "TempFrequency": 100,
        "Filter": {
            "BandPassOrder": 4,
            "BandPassLow": 0.01,
            "BandPassHigh": 0.7
        },
        "Multiple_Factor":100,
        "Second_PerEpoch": 30,
        "CorrByEpoch":
            {
                "window_epoch": 6
            }
    }

    # 预处理
    PREPROCESS_CONFIG_FILE_PATH: str = "./config/Config_preprocess.yaml"
    PREPROCESS_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "Freq": 1000
        },
        "OutputConfig": {
            "Freq": 1000
        },
        "Filter": {
            "BCGBandPassOrder": 4,
            "BCGBandPassLow": 2,
            "BCGBandPassHigh": 10,
            "ECGBandPassOrder": 3,
            "ECGBandPassLow": 1,
            "ECGBandPassHigh": 25
        }
    }
    PREPROCESS_SAVE_CHUNK_SIZE: int = 1000000

    # BCG的J峰算法定位
    DETECT_JPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Jpeak.yaml"
    DETECT_JPEAK_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "Freq": 1000
        },
        "Filter": {
            "Mode": "skip",
            "BandPassLow": 2,
            "BandPassHigh": 10
        },
        "ModelFolderPath": "./func/detect_Jpeak_model",
        "PeaksValue": 100,
        "AmpValue": 5,
        "IntervalLow": 50,
        "IntervalHigh": 140,
        "UseCPU": False,
        "DetectMethod": ""
    }
    DETECT_JPEAK_SAVE_CHUNK_SIZE: int = 100

    # ECG的R峰算法定位
    DETECT_RPEAK_CONFIG_FILE_PATH: str = "./config/Config_detect_Rpeak.yaml"
    DETECT_RPEAK_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "Freq": 1000
        },
        "Filter": {
            "Mode": "skip",
            "BandPassLow": 1,
            "BandPassHigh": 25
        },
        "PeaksValue": 200,
        "DetectMethod": ""
    }
    DETECT_RPEAK_SAVE_CHUNK_SIZE: int = 100

    # 人工纠正
    LABEL_CHECK_CONFIG_FILE_PATH: str = "./config/Config_label_check.yaml"
    LABEL_CHECK_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "Freq": 1000
        },
        "Filter": {
            "Mode": "skip",
            "BCGBandPassOrder": 2,
            "BCGBandPassLow": 2,
            "BCGBandPassHigh": 10,
            "ECGBandPassOrder": 2,
            "ECGBandPassLow": 2,
            "ECGBandPassHigh": 15
        },
        "FindPeaks" : {
            "MinInterval": 1000,
            "MinHeight": 0.5
        },
        "CustomAutoplayArgs": {
            "MoveLength": 15000,
            "MaxRange": 60000,
            "MoveSpeed": 1000
        }
    }
    LABEL_CHECK_SAVE_CHUNK_SIZE: int = 100
    LABEL_CHECK_LABEL_TRANSPARENCY: float = 0.2
    LABEL_CHECK_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"

    LABEL_CHECK_BTN_PREV_MOVE_SHORTCUT_KEY = "A"
    LABEL_CHECK_BTN_NEXT_MOVE_SHORTCUT_KEY = "D"
    LABEL_CHECK_BTN_PAUSE_SHORTCUT_KEY = "S"
    LABEL_CHECK_BTN_UPDATE_STATE_SHORTCUT_KEY = "Space"

    # 数据精同步
    PRECISELY_ALIGN_CONFIG_FILE_PATH: str = "./config/Config_precisely_align.yaml"
    PRECISELY_ALIGN_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "orgBcgFreq": 1000,
            "BCGFreq": 1000,
            "ECGFreq": 1000,
            "UseFreq": 1000
        }
    }
    PRECISELY_ALIGN_ACTION_GET_RANGE_SHORTCUT_KEY: str = "Z"
    PRECISELY_ALIGN_SAVE_CHUNK_SIZE: int = 1000000
    PRECISELY_ALIGN_SAVE_PEAK_CHUNK_SIZE: int = 100
    PRECISELY_ALIGN_LABEL_TRANSPARENCY: float = 0.2

    # 冗余数据切割和标签映射
    CUT_PAIR_FILE_CONFIG_FILE_PATH: str = "./config/Config_cut_PAIR_FILE.yaml"
    CUT_PAIR_FILE_CONFIG_NEW_CONTENT: dict = {
        "ECGFreq": 1000,
        "BCGFreq": 1000,
        "ChannelInput": {
            "Effort Tho": "PSG:" + Filename.THO_RAW,
            "Effort Abd": "PSG:" + Filename.ABD_RAW,
            "Flow T": "PSG:" + Filename.FLOWT_RAW,
            "Flow P": "PSG:" + Filename.FLOWP_RAW,
            "Snore": "PSG:" + Filename.SNORE_RAW,
            "SpO2": "PSG:" + Filename.SPO2_RAW,
            "5_class": "PSG:" + Filename.FIVE_CLASS_RAW
        },
        "OrgBCGChannelInput":{
              "OrgBCG": "OrgBCG:OrgBCG_Raw_"
        },
        "ECGChannelInput": {
            "ECG": "PSG:" + Filename.ECG_RAW
        },
        "LabelInput": {
            "SA Label": Filename.SA_LABEL_RAW
        },
        "StartTime": Filename.STARTTIME_RAW,
        "ChannelSave": {
            "Effort Tho": "PSG:" + Filename.THO_SYNC,
            "Effort Abd": "PSG:" + Filename.ABD_SYNC,
            "Flow T": "PSG:" + Filename.FLOWT_SYNC,
            "Flow P": "PSG:" + Filename.FLOWP_SYNC,
            "Snore": "PSG:" + Filename.SNORE_SYNC,
            "SpO2": "PSG:" + Filename.SPO2_SYNC,
            "5_class": "PSG:" + Filename.FIVE_CLASS_SYNC,
            "OrgBCG": "OrgBCG:" + Filename.ORGBCG_SYNC,
            "ECG": "PSG:" + Filename.ECG_SYNC
        },
        "LabelSave": {
            "SA Label": Filename.SA_LABEL_SYNC
        },
        "EndWith": {
            "Effort Tho": ENDSWITH_TXT,
            "Effort Abd": ENDSWITH_TXT,
            "Flow T": ENDSWITH_TXT,
            "Flow P": ENDSWITH_TXT,
            "Flow Patient": ENDSWITH_TXT,
            "Snore": ENDSWITH_TXT,
            "SpO2": ENDSWITH_TXT,
            "5_class": ENDSWITH_TXT,
            "SA Label": ENDSWITH_CSV,
            "StartTime": ENDSWITH_TXT,
            "OrgBCG": ENDSWITH_TXT,
            "ECG": ENDSWITH_TXT
        },
    }
    CUT_PAIR_FILE_SALABEL_EVENT: list = ["Hypopnea", "Central apnea", "Obstructive apnea", "Mixed apnea"]

    # 体动标注
    ARTIFACT_LABEL_CONFIG_FILE_PATH: str = "./config/Config_artifact_label.yaml"
    ARTIFACT_LABEL_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "orgBcgFreq": 1000,
            "BCGFreq": 1000,
            "UseFreq": 1000
        },
        "CustomAutoplayArgs": {
            "MoveLength": 15000,
            "MaxRange": 60000,
            "MoveSpeed": 1000
        }
    }
    ARTIFACT_LABEL_LABEL_TRANSPARENCY: float = 0.3
    ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY: str = "Z"
    ARTIFACT_LABEL_BTN_PREV_SHORTCUT_KEY: str = "A"
    ARTIFACT_LABEL_BTN_NEXT_SHORTCUT_KEY: str = "D"
    ARTIFACT_LABEL_BTN_PAUSE_SHORTCUT_KEY: str = "S"


    # BCG的质量标注
    BCG_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_bcg_quality_label.yaml"
    BCG_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "BCGFreq": 1000,
            "UseFreq": 1000
        }
    }
    BCG_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY: str = "A"
    BCG_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY: str = "D"
    BCG_QUALITY_LABEL_BTN_a1_SHORTCUT_KEY: str = "U"
    BCG_QUALITY_LABEL_BTN_a2_SHORTCUT_KEY: str = "I"
    BCG_QUALITY_LABEL_BTN_b1_SHORTCUT_KEY: str = "O"
    BCG_QUALITY_LABEL_BTN_b2_SHORTCUT_KEY: str = "P"
    BCG_QUALITY_LABEL_BTN_c_SHORTCUT_KEY: str = "J"

    # 呼吸可用性及间期标注
    RESP_QUALITY_LABEL_CONFIG_FILE_PATH: str = "./config/Config_resp_quality_label.yaml"
    RESP_QUALITY_LABEL_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "OrgBCGFreq": 1000,
            "ThoFreq": 100,
            "OrgBCGUseFreq": 1000,
            "ThoUseFreq": 100
        },
        "Threshold": {
            "Low": 0.65,
            "High": 0.8
        },
        "FindPeaks" : {
            "MinInterval": 300,
            "MinHeight": 0.1
        },
        "Filter": {
            "BandPassLow": 0.1,
            "BandPassHigh": 1
        }
    }
    RESP_QUALITY_LABEL_PREPROCESS_FC: int = 1
    RESP_QUALITY_LABEL_PARTS_TIME_SEC: int = 30
    RESP_QUALITY_LABEL_LABEL_TRANSPARENCY: float = 0.2
    RESP_QUALITY_LABEL_ACTION_LABEL_MULTIPLE_SHORTCUT_KEY: str = "Z"
    RESP_QUALITY_LABEL_BTN_PREV_SHORTCUT_KEY: str = "A"
    RESP_QUALITY_LABEL_BTN_NEXT_SHORTCUT_KEY: str = "D"
    RESP_QUALITY_LABEL_BTN_VALID_SHORTCUT_KEY: str = "F"
    RESP_QUALITY_LABEL_BTN_INVALID_SHORTCUT_KEY: str = "G"
    RESP_QUALITY_LABEL_BTN_RESET_SHORTCUT_KEY: str = "H"

    # 睡眠呼吸暂停事件标注
    SA_LABEL_CONFIG_FILE_PATH: str = "./config/Config_SA_label.yaml"
    SA_LABEL_CONFIG_NEW_CONTENT: dict = {
        "InputConfig": {
            "OrgBCGFreq": 1000,
            "ThoFreq": 100,
            "AbdFreq": 100,
            "FlowTFreq": 10,
            "FlowPFreq": 100,
            "SpO2Freq": 1,
            "PlotFreq": 100
        },
        "AddSecond": {
            "Front": 60,
            "Back": 60
        }
    }

    SA_LABEL_NEW_EVENT_FORMAT: dict = {
            "Index": "",  # 假设Epoch从1开始
            "Event type": "",  # 原始事件类型为空
            "Stage": "",
            "Time": "",
            "Epoch": "",
            "Date": "",
            "Duration": "",  # 计算持续时间
            "HR bef.": "",
            "HR extr.": "",
            "HR delta": "",
            "O2 bef.": "",
            "O2 min.": "",
            "O2 delta": "",
            "Body Position": "",
            "Validation": "",
            "Start": "",
            "End": "",
            "correct_Start": "",
            "correct_End":"",
            "correct_EventsType": "",  # 修正事件类型为空
            "score": -1,  # 默认分数为-1
            "isLabeled": -1,  # 默认未标记状态
            "remark": ""  # 默认备注为空
        }

    SA_LABEL_TRANSPARENCY: float = 0.05
    SA_LABEL_BTN_PREV_10s_SHORTCUT_KEY: str = "Q"
    SA_LABEL_BTN_NEXT_10s_SHORTCUT_KEY: str = "E"
    SA_LABEL_BTN_PREV_30s_SHORTCUT_KEY: str = "A"
    SA_LABEL_BTN_NEXT_30s_SHORTCUT_KEY: str = "D"
    SA_LABEL_BTN_PREV_HALF_SHORTCUT_KEY: str = "F"
    SA_LABEL_BTN_NEXT_HALF_SHORTCUT_KEY: str = "G"
    SA_LABEL_BTN_BEST_FIT_SHORTCUT_KEY: str = "B"
    SA_LABEL_BTN_EDIT_MODE_SHORTCUT_KEY: str = "Z"
    SA_LABEL_BTN_PAN_MODE_SHORTCUT_KEY: str = "X"
    SA_LABEL_BTN_CONFIRMLABEL_SHORTCUT_KEY: str = "S"
    SA_LABEL_BTN_QUICK_REMARK_WAITINGFORTALK_SHORTCUT_KEY: str = "J"
    SA_LABEL_RADIOBUTTON_OSA_SHORTCUT_KEY: str = "7"
    SA_LABEL_RADIOBUTTON_CSA_SHORTCUT_KEY: str = "8"
    SA_LABEL_RADIOBUTTON_MSA_SHORTCUT_KEY: str = "9"
    SA_LABEL_RADIOBUTTON_HPY_SHORTCUT_KEY: str = "0"
    SA_LABEL_RADIOBUTTON_1_CLASS_SHORTCUT_KEY: str = "1"
    SA_LABEL_RADIOBUTTON_2_CLASS_SHORTCUT_KEY: str = "2"
    SA_LABEL_RADIOBUTTON_3_CLASS_SHORTCUT_KEY: str = "3"
    SA_LABEL_BTN_LITTLE_CHANGED_SHORTCUT_KEY: str = "U"
    SA_LABEL_BTN_CHANGED_ON_MIDDLE_SHORTCUT_KEY: str = "I"
    SA_LABEL_BTN_BETWEEN_ARTIFACT_SHORTCUT_KEY: str = "O"
    SA_LABEL_BTN_LOW_SNR_SHORTCUT_KEY: str = "P"


    # 禁止实例化
    def __new__(cls):
        raise TypeError("Constants class cannot be instantiated")

    # 禁止修改常量
    @classmethod
    def __setattr__(cls, key, value):
        raise AttributeError("Cannot modify constants")