import os
import pandas as pd
import matplotlib.font_manager as fm
import PyPDF2

ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) #root dir
# ROOT_DIR = '/home/ubuntu/python/'

# 국문 레포트
BASE_DIR = os.path.join(ROOT_DIR, 'base_file_new') 
# 영문 레포트
BASE_DIR_EN = os.path.join(ROOT_DIR, 'base_file_en_new')
# CEC계정 bwave logo 없는 ver.
BASE_DIR_CEC = os.path.join(ROOT_DIR, 'base_file_cec_new') 
# 기관 이미지 
BASE_DIR_com = os.path.join(ROOT_DIR, 'company_img')  
# 건강검진 센터 
BASE_DIR_HOS = os.path.join(ROOT_DIR, 'base_file_hospital_new') 

# EBSI 
BASE_DIR_EBSI = os.path.join(BASE_DIR, 'EBSI')
BASE_DIR_EBSI_DETAIL = os.path.join(BASE_DIR_EBSI, 'detail')
BASE_DIR_EBSI_EN = os.path.join(BASE_DIR_EN, 'EBSI')

# 건강검진 센터 MSN (늘어날 경우 계속 추가해야함)
hos_msn = ["173", "174"]

# Font 경로
FONT_DIR = os.path.join(ROOT_DIR, 'font')

# 레포트 점수 계산 시 필요한 normative 
NORMATIVE_DIR = os.path.join(ROOT_DIR, 'normative') #폴더 경로 
N_DATA_EEG = pd.read_csv(os.path.join(NORMATIVE_DIR, 'normative_eeg_ver2.9_0220.csv')) #eeg normative
N_DATA_PPG = pd.read_csv(os.path.join(NORMATIVE_DIR, 'normative_ppg_ver2.9_0220.csv')) #ppg normative
N_DATA_MINI = pd.read_csv(os.path.join(NORMATIVE_DIR, 'normative_mini_ver1.2_0401.csv')) #mini normative

# EBSI index
brain_ebsi_index = {"foggy": 1, "mindful": 2, "talented": 3, "tense": 4, "foggy-tense": 5, "stable": 6,
                    "안개형": 1, "차분형": 2, "영재형": 3, "긴장형": 4, "안개긴장형": 5, "안정형": 6, None: 0, 0 : 0}
mind_ebsi_index = {"depreessive": 1, "anxious": 2, "mind-weak": 3, "weak-depressive": 4, "weak-anxious": 5, "stable": 6,
                   "우울형": 1, "불안형": 2, "심약형": 3, "심약우울형": 4, "심약불안형": 5, "안정형": 6, None: 0, 0: 0}

# mini EBSI index
mini_mind_ebsi_index = {1: 2, 2:3, 3:6, 4:5, 5:4, 6:1}


# EBSI LENGTH (레포트 랜덤 이미지 개수)
brain_ebsi_length = {"1_1": 7, "1_2": 3, "1_3": 14,
                   "2_1": 3, "2_2": 2, "2_3": 2,
                   "3_1": 2, "3_2": 2, "3_3": 2,
                   "4_1": 5, "4_2": 3, "4_3": 11,
                   "5_1": 5, "5_2": 3, "5_3": 6,
                   "6_1": 3, "6_2": 2, "6_3": 2}

mind_ebsi_length = {"1_1": 3, "1_2": 4, "1_3": 10,
                   "2_1": 5, "2_2": 4, "2_3": 9,
                   "3_1": 3, "3_2": 3, "3_3": 3,
                   "4_1": 3, "4_2": 4, "4_3": 10,
                   "5_1": 4, "5_2": 4, "5_3": 9,
                   "6_1": 4, "6_2": 3, "6_3": 1}


# MINI Similar Person Length
mind_person_length = {"1": 6, "2": 7, "3": 7, "4": 2, "5": 5, "6": 7}


#레포트 ebsi 치유옵션 링크 목록 25.06.30 추가
brain_ebsi_link_infos = {1:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yHTWa8gclxamYwiXzfU0_kv', 2:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yFG7JOxzMKizBht5QG5BAQ1',
                        3:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yGj3htrRbpBXl6US35kizGI', 4:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yGr-5X6dPUuNnsliBN8GLbI',
                        5:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yFfeQkLwEaAXI3nc7UNtT7O', 6:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yF6wb2gbAJMvpRO5be0mbs0',
                        'x': 157.1 ,'y': 47, 'w': 40, 'h': 12}

mind_ebsi_link_infos = {1:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yEkV8Llz3LcFUmgmS0vcZhg', 2:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yGa7_Sem8EdN7hv5EWvyHE8',
                        3:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yGHcg573uRk2_a7Cmdnz6d2', 4:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yE1P30OuC9PpCaTZMr20pOW',
                        5:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yEcsI1XUNEEoiK6cH8rP_tR', 6:'https://www.youtube.com/playlist?list=PL6T1gRDLV1yF6wb2gbAJMvpRO5be0mbs0',
                        'x': 157.1 ,'y': 90, 'w': 40, 'h': 12}

#레포트 링크목록 25.06.30 추가
link_infos = [
     {
        "url": "https://www.bwaveeeg.com/maumgyeol-partners/",
        "x": 36, "y": 247, "w": 60, "h": 13
    },
     {
        "url": "https://www.bwaveeeg.com/services/maumgyeol-mini/",
        "x": 132, "y": 247, "w": 60, "h": 13
    },
    {
        "url": "https://www.bwaveeeg.com/",
        "x": 54, "y": 272.2, "w": 52, "h": 13
    },
    {
        "url": "https://www.youtube.com/@bwave_maumgyeol",
        "x": 118.9, "y": 272.2, "w": 15, "h": 13
    },
    {
        "url": "https://www.instagram.com/maumgyeol_/",
        "x": 146.5, "y": 272.2, "w": 13, "h": 13
    },
    {
        "url": "https://blog.naver.com/bwaveeeg",
        "x": 172.9, "y": 272.4, "w": 13, "h": 13
    }
]

link_infos_en = [
     {
        "url": "https://www.bwaveeeg.com/en/services/imindwave-mini/",
        "x": 132, "y": 247.8, "w": 61, "h": 13
    },
    {
        "url": "https://www.bwaveeeg.com/en",
        "x": 56, "y": 272.2, "w": 52, "h": 13
    },
    {
        "url": "https://www.youtube.com/@bwave_maumgyeol",
        "x": 118.9, "y": 272.2, "w": 15, "h": 13
    },
    {
        "url": "https://www.instagram.com/imindwave/",
        "x": 146.5, "y": 272.2, "w": 13, "h": 13
    },
    {
        "url": "https://blog.naver.com/bwaveeeg",
        "x": 172.9, "y": 272.4, "w": 13, "h": 13
    }
]


def isNaN(num):
    if num != num:
        return "none"
    else:
        return "desc"

def createFolder(directory): #경로 생성
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
            os.chmod(directory, 0o777)
    except OSError as e:
        print('Error: Creating directory. ' + directory)
        # print(e)

# read .arc function
def transHex2Deci(b1, b2, b3): 
    C = 187499.62534099218 / (2 ** 23)
    b1 = int(b1, base=16)
    b2 = int(b2, base=16)
    b3 = int(b3, base=16)
    deci = b1 * 256 * 256 + b2 * 256 + b3 * 1
    if (deci > 2 ** 23):
        deci = deci - 2 ** 24
    deci = round(deci * C, 2)
    return deci

# read .arc function soso 24
def transHex2Deci_24(b1, b2, b3): 
    C = 201666 / (2 ** 23)
    b1 = int(b1, base=16)
    b2 = int(b2, base=16)
    b3 = int(b3, base=16)
    deci = b1 * 256 * 256 + b2 * 256 + b3 * 1
    if (deci > 2 ** 23):
        deci = deci - 2 ** 24
    deci = round(deci * C, 2)
    return deci

# 나이 그룹화 ( 점수 계산 시 필요 )
def age_modify(age, png=False):
    age_range = [20, 30, 40, 50, 60]
    if png == True:
        age = age.split("세")[0]
    try:
        if int(age) < 20:
            if int(age) < 10:
                age = "0"
            elif 10 <= int(age) <= 15:
                age = "10"
            elif 15 < int(age) < 20:
                age = "15"
        else:
            for i in age_range:
                if str(age)[0] == str(i)[0]:
                    age = str(i)
                elif int(age) >= 60:
                    age = "60"
    except TypeError:
        print('Error: not adequate age type')
    return age

# 성별 변환 
def sex_modify(sex, reportLanguage="kr"):
    if reportLanguage =="kr":
        if sex == "M":
            sex = "남"
        elif sex == "F":
            sex = "여"
        else:
            sex = sex
    else:
        pass
    return sex

def sex_modify_int(sex):

    if sex == "M" or sex == "남":
        sex = 0
    elif sex == "F" or sex == "여":
        sex = 2
    else:
        pass
    return sex

# 레포트(6p) 제작 시 필요 text (영/국문)
def define_norm_text(age, signal, reportLanguage="kr"):
    if reportLanguage =="en":
        if signal == "두뇌":
            signal = "brain"
        else:
            signal = "mind"

        if age == "0":
            text = "The distribution of " + signal + " health scores for children under 10 years old "
        elif age == "10":
            text = "The distribution of " + signal + " health scores for 10 to 15 year olds"
        elif age == "15":
            text = "The distribution of " + signal + " health scores for 15 to 19 year olds"
        elif age == "60":
            text = "The distribution of " + signal + " health score for the 60+ group"
        else:
            text = "The distribution of " + signal + " health score for the " + age + "'s group"
    else:
        if age == "0":
            text = "10세 미만(학전기 및 초등 저학년) " + signal + "건강지수 분포"
        elif age == "10":
            text = "10세~15세 (초등 고학년 및 중학생) " + signal + "건강지수 분포"
        elif age == "15":
            text = "15세~19세 (고등학생) " + signal + "건강지수 분포"
        elif age == "60":
            text = "60대 이상 " + signal + "건강지수 분포"
        else:
            text = age + "대 " + signal + "건강지수 분포"
    return text

# 레포트 text 표기 시 필요 (영/국문)
def change_dq(dq:str, reportLanguage:str = "kr"):
    if reportLanguage =="en":
        dq = dq.capitalize()
    else:
        if dq == "high":
            dq = "상"
        elif dq == "middle":
            dq = "중"
        elif dq == "low":
            dq = "하"
    return dq


# 기기 별 sampling rate 이 다름 
def cal_samplefreq(file, device):  # file 받아오는 인수 추가 (파일명으로 soso24 구별 위해 )
    samplefreq = 0
    _, extension = os.path.splitext(file)
    if device == 'laxtha' or device == 'laxtha_old'or device == 'linkband':
        samplefreq = 250
    if device == 'soso' or device == 'compumedic' or device == 'crown' or device == 'fnirs' :
        samplefreq = 256
    if device == "cgx":
        samplefreq = 500
    if device == "neuroscan" or device == "egi":
        samplefreq = 1000
    if device == "arduino":
        samplefreq = 189
    if device == "mini":
        samplefreq = 1000/40
    if device == 'light_soso':  # soso24 sampling rate 변경 이슈
        if file.split('/')[-1].split('_')[1] =='02':
            samplefreq = 250
          

        else :
            samplefreq = 256

        
    assert samplefreq != 0, "{} is unsupported device.".format(device)
    return samplefreq

def encrypt_pdf_old(RESULT_DIR, pdf_filename, birth):
    org = os.path.join(RESULT_DIR, pdf_filename)
    new = os.path.join(RESULT_DIR, pdf_filename)
    password = birth

    file = open(org ,'rb')
    reader = PyPDF2.PdfReader(file)
    writer = PyPDF2.PdfWriter()
    
    for p in range(len(reader.pages)):
        writer.add_page(reader.pages[p])
    writer.encrypt(password)
    
    new_file = open(new, 'wb')
    writer.write(new_file)

    new_file.close()
    file.close()
    
    
import fitz

# PDF 암호화 함수 
def encrypt_pdf(RESULT_DIR, pdf_filename, password):
    input_pdf_path = os.path.join(RESULT_DIR, pdf_filename)
    output_pdf_path = os.path.join(RESULT_DIR, pdf_filename.split('temp_')[1])
    doc = fitz.open(input_pdf_path)
    encrypt_meth = fitz.PDF_ENCRYPT_AES_256
    doc.save(output_pdf_path, encryption=encrypt_meth, owner_pw = password, user_pw=password)
    doc.close()


# 뇌파 주파수 대역 밴드 
FREQ_BANDS = {'theta': [4, 8], 
              'low-alpha': [8, 10],
              'high-alpha': [10, 12],
              'low-beta': [12, 15],
              'middle-beta': [15, 20],
              'high-beta': [20, 30],
              'gamma': [30, 40]}

# 뇌파 주파수 대역 밴드에 alpha 파 추기 
FREQ_BANDS_alpha = {'theta': [4, 8], 
                    'alpha': [8, 12],
                    'low-alpha': [8, 10],
                    'high-alpha': [10, 12],
                    'low-beta': [12, 15],
                    'middle-beta': [15, 20],
                    'high-beta': [20, 30],
                    'gamma': [30, 40]}


#파일 삭제 위한 생성파일 리스트
REPORT_FILELIST = [
 'ANS_activity.png',
 'ANS_balance.png',
 'brain_activity.png',
 'brain_balance.png',
 'brain_flexibility.png',
 'brain_intelligence.png',
 'eeg_mean.png',
 'eeg_norm.png',
 'eeg_score.png',
 'first_1.jpg',
 'first_2.jpg',
 'first_3.jpg',
 'first_4.jpg',
 'first_5.jpg',
 'first_6.jpg',
 'first_7.jpg',
 'ppg_mean.png',
 'ppg_norm.png',
 'ppg_score.png',
 'pse_depress.png',
 'pse_unrest.png',
 'second_2.jpg',
 'second_3.jpg',
 'second_4.jpg',
 'second_5.jpg',
 'second_6.jpg',
 'self_understanding.png',
 'stress_index.png',
 'stress_resistance.png',
 'third_2.jpg',
 'third_4.jpg',
 'third_5.jpg',
 'first_2_1.jpg'
 ]

EBSI_FILELIST=[
    'eeg_ebsi_radar.png',
    'first_1_ebsi.jpg',
    'first_2_ebsi.jpg',
    'first_3_ebsi.jpg',
    'first_4_ebsi.jpg',
    'ppg_ebsi_radar.png',
    'first_8.jpg',
    'first_list.jpg'   #24.12.06 추가
]

# mddUse==1 일 때 생성되는 우울증 진단 페이지 (PDF 합본 후 삭제 대상)
MDD_FILELIST = [
    'mdd_report.jpg'
]

def im():
    # 이미지 읽기
    import cv2 as cv
    end = cv.imread("C:/Users/bwave/Desktop/bwave_basic/end.jpg", cv.IMREAD_UNCHANGED)
    resize_img = cv.resize(end, (1280, 720))
    winname = "end"
    cv.namedWindow(winname)  # create a named window
    cv.moveWindow(winname, 200, 100)
    cv.imshow(winname, resize_img)
    cv.waitKey(0)
    cv.destroyAllWindows()

def bp():
    import winsound as sd
    fr = 20000
    du = 3000
    sd.Beep(fr, du)

def insert_info(dic, sex, age, date=0, patient=0):
    temp = list(dic.items())
    temp.insert(1, ('sex', sex))
    temp.insert(1, ('age', int(age)))
    temp.insert(1, ('date', date))
    temp.insert(1, ('patient', patient))
    dic = dict(temp)
    return dic


from numba import jit
import numpy as np
@jit(nopython=True)
def kolmogorov_complexity(arr):
    mean = arr.mean()
    for i in range(len(arr)):
        if arr[i] >= mean:
            arr[i] = 1
        else:
            arr[i] = 0
    n = len(arr)
    c = 1
    l = 1
    i = 0
    k = 1
    k_max = 1
    stop = 0
    while stop == 0:
        if arr[i + k - 1] != arr[l + k - 1]:
            if k > k_max:
                k_max = k
            i = i + 1
            if i == l:
                c = c + 1
                l = l + k_max
                if l + 1 > n:
                    stop = 1
                else:
                    i = 0
                    k = 1
                    k_max = 1
            else:
                k = 1
        else:
            k = k + 1
            if l + k > n:
                c = c + 1
                stop = 1
    b = n / np.log2(n)
    complexity = c / b
    return complexity
