import directory
from EEG import EEG
from PPG import PPG
import PNG_REPORT
import PNG_EBSI
import PDF_ALL
import PNG_MDD_REPORT
import MDD_classifier
import traceback
import os
import sys
import json
import time
import shutil
import datetime
import pandas as pd
import PNG_classifier as PNG_classifier
import  classifier as classifier
# filename
# device
# sex
# age

if __name__ == "__main__":
    start_time = time.perf_counter()
    # sys.argv로 들어오는 값은 모두 str type 으로 들어옴.
    # 웹에서 넘겨주는 값들 

    report_ok = {'result': 1, 'ebsi': 0}
#넘겨주는 값 null 일 경우 오류 처리 
    try:
        file = sys.argv[1]      #뇌파 파일
        device = sys.argv[2]    #측정기기 laxtha, soso
        number = sys.argv[3]    #넘버
        date = sys.argv[4]
        name = sys.argv[5]      #이름
        sex = sys.argv[6]       # 성별, M - 남자 , F - 여자
        age = sys.argv[7]       # 나이(만)
        depressed = float(sys.argv[8])  # K-DEP, 우울장애
        unrest = float(sys.argv[9])  # K-ANX, 불안장애
        reportLanguage = sys.argv[10] # REPORT 언어
        RESULT_DIR = sys.argv[11] # 저장 PATH
        password = sys.argv[12] # PDF password 여부
        birth = sys.argv[13] # PDF password (사용자 생년월일)
        eeg_only = bool(int(sys.argv[14])) # eeg레포트만
        ppg_only = bool(int(sys.argv[15])) # ppg레포트만
        ebsi = bool(int(sys.argv[16])) # EBSI 레포트 생성 여부
        msn = sys.argv[17] # CECLAB 구분하기 위해 받음.
        ai_use = sys.argv[18]
        mdd_use = sys.argv[19] # 1: 우울증 진단 페이지 추가, 2(그 외): 기존과 동일
        # MDD 페이지 사용 시 PDF 비밀번호 설정 안 함
        if mdd_use == '1':
            password = 'N'

    # print("file:", file)
    # print("device:", device)
    # print("number:", number)
    # print("date:", date)
    # print("name:", name)
    # print("sex:", sex)
    # print("age:", age)
    # print("depressed:", depressed)
    # print("unrest:", unrest)
    # print("reportLanguage:", reportLanguage)
    # print("RESULT_DIR:", RESULT_DIR)
    # print("password:", password)
    # print("birth:", birth)
    # print("eeg_only:", eeg_only)
    # print("ppg_only:", ppg_only)
    # print("ebsi:", ebsi)
    # print("msn:", msn)
    # print("ai_use:", ai_use)

    except Exception as e:  
            print(traceback.format_exc())
            report_ok['result'] = -2999

    report_ok = json.dumps(report_ok) 



    
    current_time = str(round(datetime.datetime.utcnow().timestamp() * 1000))
    
    # 일괄생성시 설문지는 같고 파일이 다를 경우를 대비하여 폴더이름에 시간 추가
    RESULT_DIR = os.path.join(RESULT_DIR, current_time + name)
    directory.createFolder(RESULT_DIR)
    print("RESULT_DIR joined = {}".format(RESULT_DIR))
    

    s_time = time.perf_counter()

    """
    EEG & PPG 계산 part 
    """

    if (eeg_only==False) and (ppg_only==False):
        eeg = EEG(file, RESULT_DIR, age=age, device=device, reportLanguage=reportLanguage)  #eeg.py 에 있는 클래스 호출
        try:
            eeg.run_function_eeg()
            eeg.report['eeg_code'] = 1   # 오류 없으면 eeg_code = 1 (성공했다는 뜻) default 값은 -2005
            print("EEG OK")
        except Exception as e:  
            print(traceback.format_exc()) # 오류 뱉고, ppg는 괜찮을 수도 있으니 ppg_only=True 로 
            ppg_only=True
        eeg_json_val = json.dumps(eeg.report)  # 웹에 던져주기 위해 json 으로 묶음 
        print(eeg_json_val)
        
        ppg = PPG(file, RESULT_DIR, age=age, device=device, depressed=depressed, unrest=unrest, reportLanguage=reportLanguage) # ppg.py에 있는 클래스 호출 
        try:
            ppg.run_function_ppg()
            ppg.report['ppg_code'] = 1 # eeg 와 마찬가지, ppg_code 의 default 값은 -2006
            print("PPG_OK")
        except Exception as e:
            print(traceback.format_exc())
            eeg_only=True
        ppg_json_val = json.dumps(ppg.report)
        print(ppg_json_val)

    elif eeg_only == True:
        eeg = EEG(file, RESULT_DIR, age=age, device=device, reportLanguage=reportLanguage)
        eeg.report['ppg_code'] = 1   # ppg_code 가 -2006일 경우 오류 코드이기 떄문에 임시로 1로 지정 후 나머지 값들은 0으로 세팅 
        eeg.report['ppgScore'] = 0
        eeg.report['ppgOnlyScore'] = 0
        eeg.report['dataQuality_ppg'] = None
        eeg.report['ppg_subtype'] = None
        try:
            eeg.run_function_eeg()
            eeg.report['eeg_code'] = 1
            print("EEG OK")
        except Exception as e: 
            eeg.report = None
            print(traceback.format_exc())
        eeg_json_val = json.dumps(eeg.report)
        print(eeg_json_val)

    elif ppg_only == True:
        ppg = PPG(file, RESULT_DIR, age=age, device=device, depressed=depressed, unrest=unrest, reportLanguage=reportLanguage)
        ppg.report['eeg_code'] = 1   # eeg_code 가 -2005일 경우 오류 코드이기 떄문에 임시로 1로 지정 후 나머지 값들은 0으로 세팅 
        ppg.report['eegScore'] = 0
        ppg.report['dataQuality_eeg'] = None
        ppg.report['eeg_subtype'] = None
        try:
            ppg.run_function_ppg()
            ppg.report['ppg_code'] = 1
        except Exception as e: 
            ppg.report = None
            print(traceback.format_exc())
        ppg_json_val = json.dumps(ppg.report)
        print(ppg_json_val)
        
    report_ok = {'result': 1, 'ebsi': 0}

    if (eeg_only==False) and (ppg_only==False)and (ai_use=='1'):
        feature_4class= pd.DataFrame([{"eeg":eeg.eeg_score, "ppg_hrv_only":ppg.hrv_only_score,"theta": eeg.rel[0],"l_alpha": eeg.rel[2],"h_alpha": eeg.rel[3],"l_beta": eeg.rel[4],"m_beta": eeg.rel[5],"h_beta": eeg.rel[6],"gamma": eeg.rel[7],
        "com": eeg.com,"faa": eeg.faa,"apf_freq": eeg.peak_x,"apf_psd": eeg.peak_y,"tp": ppg.fd['TP'].values[0][0],"vlf": ppg.fd['VLF'].values[0][0],"lf": ppg.fd['LF'].values[0][0],"hf": ppg.fd['HF'].values[0][0],
        "sns": ppg.sns,"pns": 100-int(ppg.sns),"si": ppg.si,"sdnn": ppg.sdnn,"rmssd": ppg.rmssd,"age": age,"sex": directory.sex_modify_int(sex)}])

        predict_result = {
                k: {
                    'mean': round(v['mean'] * 100, 1),
                    'lo': round(v['lo'] * 100, 1),
                    'hi': round(v['hi'] * 100, 1),
                }
                for k, v in classifier.predict(feature_4class).items()
            }
        PNG_classifier.make_classifier(file, RESULT_DIR, number=number, name=name, sex=sex, age=age, date=date,eeg_only=eeg_only,
                                        ppg_only=ppg_only, reportLanguage=reportLanguage, predict_result=predict_result)

    """
    MDD(우울증) AI 진단 페이지 - mdd_use=='1' 일 때만 EBSI 리포트 앞에 한 장 추가.
    EEG+PPG 신호가 둘 다 있어야 예측 가능하므로 eeg_only/ppg_only 모드에서는 스킵.
    """
    report_ok['mdd_code'] = 0
    if (eeg_only == False) and (ppg_only == False) and (mdd_use == '1'):
        try:
            eeg_ch1, eeg_ch2 = eeg.raw.get_data()
            ppg_raw = ppg.raw.values
            dep_prob = MDD_classifier.predict(eeg_ch1, eeg_ch2, ppg_raw,
                                               fs_eeg=eeg.samplefreq, fs_ppg=ppg.samplefreq)
            if dep_prob is not None:
                PNG_MDD_REPORT.make_mdd_report(dep_prob, RESULT_DIR, number=number, name=name,
                                                sex=directory.sex_modify(sex, reportLanguage=reportLanguage), age=age,
                                                date=date, reportLanguage=reportLanguage)
                report_ok['mdd_code'] = 1
                report_ok['mdd_probability'] = round(dep_prob, 4)
            else:
                print("MDD: 잡음이 많아 분석 가능한 구간이 없습니다")
        except Exception as e:
            print(traceback.format_exc())

    """
    REPORT 생성 part
    """
    try:

        PNG_REPORT.make_report(file, RESULT_DIR, depressed, unrest, number, name, directory.sex_modify(sex, reportLanguage=reportLanguage), age, date,
                        eeg_only=eeg_only, ppg_only=ppg_only, reportLanguage=reportLanguage, msn=msn)
        PNG_EBSI.make_ebsi(file, RESULT_DIR, age=age, sex=directory.sex_modify(sex, reportLanguage=reportLanguage), number=number, name=name, date=date, eeg_only=eeg_only, ppg_only=ppg_only, reportLanguage=reportLanguage, msn=msn)
    except:
        print(traceback.format_exc())
        report_ok['result'] = -2009

    try:

        PDF_ALL.make_pdf(RESULT_DIR, number+"_"+name, password=password, birth=birth, eeg_only=eeg_only, ppg_only=ppg_only, msn=msn, eeg_subtype = eeg.report['eeg_subtype'], ppg_subtype = ppg.report['ppg_subtype'], reportLanguage=reportLanguage)
    except:
        print(traceback.format_exc())
        report_ok['result'] = -2009
            
    try:
        os.remove(os.path.join(RESULT_DIR, os.path.join(RESULT_DIR, file.split('/')[-1][:-4] + '_eeg.csv')))
        os.remove(os.path.join(RESULT_DIR, os.path.join(RESULT_DIR, file.split('/')[-1][:-4] + '_ppg.csv')))
    except FileNotFoundError:
        pass
    report_ok['date'] = sys.argv[4]
    report_ok['number'] = sys.argv[3] 
    report_ok['name'] = sys.argv[5]
    report_ok['sex'] = sys.argv[6]
    report_ok['age'] = sys.argv[7]

    #result_data에 성별 평균, 연령대 평균, 전체평균 추가 25.07.30
    info = pd.read_csv(os.path.join(directory.ROOT_DIR, 'all_info.csv'))
    info.index = ['eeg_mean', 'eeg_std', 'ppg_mean', 'ppg_std']

    sex_api = directory.sex_modify(sex, reportLanguage= "kr")#all_info.csv에 성별 구분 남/여 로 돼있기 때문에 성별데이터 남/여로 변환 25.07.30
    age_api = directory.age_modify(age)#all_info.csv에 연령대별로 데이터 구분되어 있기 때문에 10, 20, 30 등 연령대로 변환

    report_ok['sex_eeg_mean'] = round(info[sex_api]['eeg_mean'],2)
    report_ok['sex_ppg_mean'] = round(info[sex_api]['ppg_mean'],2)

    report_ok['age_eeg_mean'] = round(info[age_api]['eeg_mean'],2)
    report_ok['age_ppg_mean'] = round(info[age_api]['ppg_mean'],2)

    report_ok['all_eeg_mean'] = round(info['all']['eeg_mean'],2)
    report_ok['all_ppg_mean'] = round(info['all']['ppg_mean'],2)
    


    report_ok = json.dumps(report_ok) 
    print(report_ok)

    shutil.rmtree(RESULT_DIR)

    end_time = time.perf_counter()
    #print("eeg_only : {}".format(eeg_only))
    #print("ppg_only : {}".format(ppg_only))
    #print(f"python time elapsed : {int(round((end_time - start_time) * 1000))}ms")
