package com.dbs.mplus.fatima.consent;

import android.os.AsyncTask;

import com.dbs.mplus.fatima.consent.comm.MPlusHttpClient;
import com.dbs.mplus.fatima.consent.model.SavedConsent;
import com.dbs.mplus.fatima.consent.sign.SignWrapper;
import com.dbs.mplus.fatima.consent.webservice.ConsentWSWrapper;
import com.dbs.mplus.fatima.framework.processor.msg.ConsentMessage;
import com.dbs.mplus.fatima.framework.util.MPlusHashUtil;
import com.dbs.mplus.fatima.framework.util.MPlusLogUtil;
import com.dbs.mplus.fatima.framework.util.MPlusStringUtil;

import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import kr.co.clipsoft.eform.EFormToolkit;
import kr.co.clipsoft.eform.event.IEventHandler;
import kr.co.clipsoft.eform.event.ResultEventArgs;
import kr.co.clipsoft.eform.information.ResultRecordFile;

/**
 * 결과 값 반환(저장, 임시저장, 임시저장2) 이벤트 핸들러
 * 동의서 저장 처리기
 */
class EFormSaveHandler implements IEventHandler<ResultEventArgs> {

    private EFormToolkit toolkit;

    private ConsentMessage consentMsg;

    private String deviceUUID;


    public EFormSaveHandler(EFormToolkit toolkit, ConsentMessage consentMsg, String deviceId) {
        this.toolkit = toolkit;
        this.consentMsg = consentMsg;
        this.deviceUUID = deviceId;
    }

    @Override
    public void eventReceived(Object sender, ResultEventArgs e) {
        ArrayList<ResultRecordFile> audioPath = e.getAudioPath();
        int formSeq = e.getFormOpenSequence();
        String dataXml = e.getDataXml();
        MPlusLogUtil.DEBUG(this.getClass(), "동의서 Form sequence:" + formSeq);
        Map<String, String> formParamMap = this.consentMsg.getFormParamMapList().get(formSeq-1);
        // 이미지 저장경로 받음
        ArrayList<String> imagePath = e.getImagePath();
        // 동의서 파일 경로
        String eptFilePath = e.getTempFilePath();
        MPlusLogUtil.DEBUG(this.getClass(), "동의서 EPT파일 경로:" + eptFilePath); // /storage/emulated/0/CLIPe-Form/Temp/20161124_114225_067.ept
        StringBuffer eptXmlData = new StringBuffer("");
        if(eptFilePath != null && "".equals(eptFilePath) == false) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(eptFilePath));
                while(br.ready()) {
                    eptXmlData.append(br.readLine());
                }
            } catch (Exception e1) {
                e1.printStackTrace();
                this.toolkit.sendEFormViewerCancelEvent("EPT 파일을 읽을수 없습니다.");
            }
        }
        MPlusLogUtil.DEBUG(this.getClass(), "동의서 EPT파일 내용:" + eptXmlData);

        // XML 데이터 객체로 변환
        SavedConsent consent = new SavedConsent();
        consent.parse(dataXml);
        MPlusLogUtil.DEBUG(this.getClass(), "객체로 변환 XML -> SavedConsent:" + consent);

        SaveTask saveTask = new SaveTask();
        saveTask.setDeviceUUID(this.deviceUUID);
        saveTask.setFormParamMap(formParamMap);
        saveTask.setImagePathList(imagePath);
        saveTask.setSavedConsent(consent);
        saveTask.setToolkit(this.toolkit);
        saveTask.setUserId(this.consentMsg.getUserId());
        saveTask.setEptXmlData(eptXmlData.toString());
        saveTask.setVisitType(this.consentMsg.getParamMap().get("visitType"));
        switch(e.getResultCode()) {
            // 저장
            case SAVE:
                MPlusLogUtil.DEBUG(this.getClass(), "저장:" + dataXml);
                // 동의서 저장 Task 실행
                saveTask.setSave(true);
                saveTask.execute();
                break;
            // 임시저장
            case TEMP_SAVE:
            case TEMP_SAVE2:
                saveTask.setSave(false);
                saveTask.execute();
                MPlusLogUtil.DEBUG(this.getClass(), "TEMP 저장:" + dataXml);
                break;
        }
    }


    /**
     * 저장 태스크
     */
    private class SaveTask extends AsyncTask<Void, Void, Void> {
        private String deviceUUID;
        private EFormToolkit toolkit;
        private String userId;
        private List<String> imagePathList;
        private Map<String, String> formParamMap;
        private SavedConsent savedConsent;
        private String eptXmlData;
        // 내원구분
        private String visitType;

        // 저장여부
        private boolean save;

        private ConsentWSWrapper webService;

        public SaveTask() {
            this.webService = ConsentWSWrapper.getInstance();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                // TODO 저장, 임시저장 전 상태확인
                MPlusLogUtil.DEBUG(this.getClass(), "동의서 상태 확인 시작");
                String rid = formParamMap.get("rid");
                MPlusLogUtil.DEBUG(this.getClass(), "동의서 rid:" + rid);
                if(rid != null && rid.isEmpty() == false) {
                    int consentMstRid = MPlusStringUtil.convertStringToInteger(rid);
                    String consentState = formParamMap.get("consentState");

                    int result = webService.checkConsentState(consentMstRid, consentState);
                    if (result == 1) {
                        this.toolkit.sendEFormViewerCancelEvent("이미 작성된 동의서입니다");
                        return null;
                    }
                }

                if(save) {
                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 저장 시작");
                    JSONObject imageFileJsonObj = new JSONObject();
                    StringBuffer hashValue = new StringBuffer();
                    for(int i=0; i<this.imagePathList.size(); i++) {
                        File imageFile = new File(imagePathList.get(i));
                        MPlusLogUtil.DEBUG(this.getClass(), "동의서 이미지 업로드 filePath:" + imageFile.getAbsolutePath());
                        String fileName = MPlusStringUtil.convertDateString(new Date(), "yyyyMM/dd/") + imageFile.getName();
                        MPlusLogUtil.DEBUG(this.getClass(), "동의서 이미지 업로드 fileName:" + fileName);
                        // 동의서 이미지 업로드
                        new MPlusHttpClient().uploadPicture(ConsentConstants.CONSENT_IMAGE_UPLOAD_URL, imageFile, fileName);
                        // 업로드된 이미지 json 추가
                        imageFileJsonObj.put("imageFile"+(i+1), fileName);

                        // 전자서명을 위하여 해쉬값 추가
                        hashValue.append(this.createHashValue(imageFile));
                        // 맨 뒤에는 구분자 넣지 않음
                        if((i+1) < this.imagePathList.size()) {
                            hashValue.append("^");
                        }

                        // 이미지 삭제
                        imageFile.delete();
                    }

                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 저장 EptXmlData:" + this.eptXmlData);
                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 저장 DataXml:" + this.savedConsent.getDataXml());
                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 저장 hashValue:" + hashValue);

                    String certResult = SignWrapper.getInstance().signData(this.userId, hashValue.toString());
                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 저장 certResult:" + certResult);
                    webService.saveCompleteAll(formParamMap, this.userId, this.savedConsent.getDataXml(), this.eptXmlData, this.deviceUUID, this.visitType,
                            "CERTIFY_CMP", imageFileJsonObj, hashValue.toString(), certResult);
                } else {
                    MPlusLogUtil.DEBUG(this.getClass(), "동의서 임시저장 시작");
                    webService.saveTempData(this.formParamMap, this.userId, this.savedConsent.getDataXml(), this.eptXmlData, this.deviceUUID, this.visitType);
                }
            } catch (Exception e) {
                e.printStackTrace();
                this.toolkit.sendEFormViewerCancelEvent(e.getMessage());
                return null;
            }
            MPlusLogUtil.DEBUG(this.getClass(), "동의서 처리 완료");
            this.toolkit.sendEFormViewerOkEvent(); // 정상 처리 되었다고 뷰어에 이벤트 전달
            return null;
        }

        /**
         * HashValue 생성
         * @param consentImageFile
         * @return
         * @throws Exception
         */
        private String createHashValue(File consentImageFile) throws Exception {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(consentImageFile));
            byte[] fileBuf = new byte[bis.available()];
            bis.read(fileBuf);
            return MPlusHashUtil.sha256(null, fileBuf);
        }

        public void setDeviceUUID(String deviceUUID) {
            this.deviceUUID = deviceUUID;
        }

        public void setToolkit(EFormToolkit toolkit) {
            this.toolkit = toolkit;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public void setImagePathList(List<String> imagePathList) {
            this.imagePathList = imagePathList;
        }

        public void setFormParamMap(Map<String, String> formParamMap) {
            this.formParamMap = formParamMap;
        }

        public void setSavedConsent(SavedConsent savedConsent) {
            this.savedConsent = savedConsent;
        }

        public void setSave(boolean save) {
            this.save = save;
        }

        public void setEptXmlData(String xmlData) { this.eptXmlData = xmlData; }

        public void setVisitType(String visitType) { this.visitType = visitType; }
    }
}