package com.dbs.mplus.knuh.consent;

import android.content.Context;
import android.os.Build;
import android.util.Log;

import com.dbs.mplus.knuh.BuildConfig;
import com.dbs.mplus.knuh.R;
import com.dbs.mplus.knuh.activity.ConsentActivity;
import com.dbs.mplus.knuh.adapter.ConsentHistoryAdapter;
import com.dbs.mplus.knuh.consent.sign.SignWrapper;
import com.dbs.mplus.knuh.httpTask.CallBack;
import com.dbs.mplus.knuh.httpTask.HttpImageUpload;
import com.dbs.mplus.knuh.httpTask.HttpSoapConnection;
import com.dbs.mplus.knuh.util.ConsentConfig;
import com.dbs.mplus.knuh.util.Util;

import org.json.JSONObject;
import org.ksoap2.serialization.SoapObject;

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.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.xml.transform.Result;

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.type.enumtype.ResultCode;

public class EFormSaveHandler implements IEventHandler<ResultEventArgs>, CallBack {

  private static final String TAG = "EFormSaveHandler";
  private Context mContext;
  private EFormToolkit eFormToolkit;
  private HashMap consentData;
  private ConsentActivity instance = null;

  private CallBack callBack = null;

  private HashMap saveMapData = null;

  private String apiType = "";
  private String buttonType = "";

  public EFormSaveHandler(Context mContext, EFormToolkit eFormToolkit, HashMap consentData, String apiType) {
    this.mContext     = mContext;
    this.eFormToolkit = eFormToolkit;
    this.consentData  = consentData;
    this.callBack     = this;
    this.instance     = (ConsentActivity) mContext;
    this.apiType      = apiType;
  }

  @Override
  public void eventReceived(Object o, ResultEventArgs resultEventArgs) {
    saveMapData = createSaveData(resultEventArgs, consentData);
    saveProcess(saveMapData, resultEventArgs);

  }

  private HashMap createSaveData(ResultEventArgs eventArgs, HashMap consentData) {
    HashMap resultMap = new HashMap();
    int index = eventArgs.getFormOpenSequence() - 1;
    Log.e(TAG, "index -- > " + index);
    HashMap<String, String> globalParam = (HashMap<String, String>) consentData.get("globalParam");
    ArrayList<HashMap<String, String>> formListParam = (ArrayList<HashMap<String, String>>) consentData.get("formListParam");
    HashMap<String, String> formParam = (HashMap<String, String>) formListParam.get(index);

    String userId            = Util.getStringPreference(mContext, "userInfo", "userId");
    String userDeptCd        = Util.getStringPreference(mContext, "userInfo", "deptCd");
    String patientCode       = globalParam.get("parCMDCHD_1PatientNo");
    String clnDeptCode       = globalParam.get("parCMDCHD_1DepartmentCd");
    int formRid              = Integer.parseInt(formParam.get("formRid"));
    String formCd            = formParam.get("formCd");
    int consentMstRid        = Integer.parseInt(formParam.get("rid"));
    int rewriteConsentMstRid = 0;
    String dataXml           = eventArgs.getDataXml();
    String deviceType        = "AND";
    String deviceIdentNo     = Util.getMACAddress();
    String vistType          = globalParam.get("ordType");
    String hosType           = BuildConfig.INST_CD;
    String clnDate           = globalParam.get("parCMDCHD_1VisitDt"); //입원은 inDd, 외래는 ordDd;
    String ward              = globalParam.get("ward");
    String roomCd            = globalParam.get("parNUR_Fast_HospitalroomNo");
    int orderNo              = 0;
    String orderName         = "";
    String orderCd           = "";
    String ocrCode           = formParam.get("parCMSGBD_ocr_cd");
    int cretNo               = Integer.parseInt(globalParam.get("parCMSGBD_Cretno") == null ? "0" : globalParam.get("parCMSGBD_Cretno"));
    String createUserName    = userId;
    String modifyUserName    = userId;
    String mainDrId          = globalParam.get("mainDrId");
    String pageCnt           = String.valueOf(eventArgs.getTotalPagesCount());
    String actKind           = ""; // (임시 확인 : P), 인증 C, 삭제 CP
    String clientType        = ConsentConfig.CLIENT_TYPE;
    String opRsrvNo          = globalParam.get("parCMDCBD_OpRsrvNo");
    String dschDd            = globalParam.get("dschDd");

    String eptFilePath = eventArgs.getTempFilePath();
    StringBuffer formXml = new StringBuffer();
    if (eptFilePath != null && "".equals(eptFilePath) == false) {
      try {
        BufferedReader br = new BufferedReader(new FileReader(eptFilePath));
        while (br.ready()) {
          formXml.append(br.readLine());
        }
      } catch (Exception e1) {
        e1.printStackTrace();
        this.eFormToolkit.sendEFormViewerCancelEvent(mContext.getString(R.string.notReadEptFile));
      }
    }

    File eptFile = new File(eptFilePath);
    eptFile.delete();

    resultMap.put("userId", userId);
    resultMap.put("userDeptCd", userDeptCd);
    resultMap.put("patientCode", patientCode);
    resultMap.put("clnDeptCode", clnDeptCode);
    resultMap.put("formRid", formRid);
    resultMap.put("formCd", formCd);
    resultMap.put("consentMstRid", consentMstRid);
    resultMap.put("rewriteConsentMstRid", rewriteConsentMstRid);
    resultMap.put("formXml", formXml.toString());
    resultMap.put("dataXml", dataXml);
    resultMap.put("deviceType", deviceType);
    resultMap.put("deviceIdentNo", deviceIdentNo);
    resultMap.put("vistType", vistType);
    resultMap.put("hosType", hosType);
    resultMap.put("clnDate", Util.removeSlashStr(clnDate));
    resultMap.put("ward", ward);
    resultMap.put("roomCd", roomCd);
    resultMap.put("orderNo", orderNo);
    resultMap.put("orderName", orderName);
    resultMap.put("orderCd", orderCd);
    resultMap.put("ocrCode", ocrCode);
    resultMap.put("cretNo", cretNo);
    resultMap.put("createUserName", createUserName);
    resultMap.put("modifyUserName", modifyUserName);
    resultMap.put("mainDrId", mainDrId);
    resultMap.put("pageCnt", pageCnt);
    resultMap.put("clientType", clientType);
    resultMap.put("opRsrvNo", opRsrvNo);
    resultMap.put("dschDd", dschDd);

    return resultMap;
  }

  private void saveProcess(HashMap saveData, ResultEventArgs eventArgs) {
    buttonType = eventArgs.getResultCode().toString();
    Log.e(TAG, "buttonType -- > " + buttonType);

    if (Util.checkNetwork(mContext) != true) {
      eFormToolkit.sendEFormViewerCancelEvent(mContext.getString(R.string.networkError));
    } else {
      switch (eventArgs.getResultCode()) {
        case SAVE:       // 인증저장
          saveData.putAll(imageUpload(eventArgs));
          saveData.put("actKind", "C");
          saveData.put("consentState", "CERTIFY_CMP");
//        eFormToolkit.sendEFormViewerOkEvent();

          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_CONFIRM_CERTIFY, saveData, callBack);
          break;
        case TEMP_SAVE:  // 임시저장
          saveData.put("actKind", "T");
          saveData.put("consentState", "TEMP");
          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_TEMP, saveData, callBack);
          break;
        case TEMP_SAVE2: // 확인저장
          saveData.putAll(imageUpload(eventArgs));
          saveData.put("actKind", "T");
          saveData.put("consentState", "ELECTR_CMP");

          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_CONFIRM_CERTIFY, saveData, callBack);
          break;
      }
    }
  }

  private HashMap<String, String> imageUpload(ResultEventArgs eventArgs) {
    HashMap<String, String> saveData = new HashMap<String, String>();

    ArrayList<String> imagePathList = eventArgs.getImagePath();
    String imageFileSize = "";

    JSONObject imageFileJsonObj = new JSONObject();
    StringBuffer hashValue = new StringBuffer();
    try {
      for (int i = 0; i < imagePathList.size(); i++) {
        File imageFile = new File(imagePathList.get(i));
        String fileName = Util.convertDateString(new Date(), "yyyyMM/dd/") + imageFile.getName();

        imageFileSize += String.valueOf(imageFile.length()/1024);
        if (imagePathList.size() - 1 > i) {
          imageFileSize += ", ";
        }

        // 동의서 이미지 업로드
        HttpImageUpload imageUpload = new HttpImageUpload(ConsentConfig.CONSENT_IMAGE_UPLOAD_URL, imageFile, fileName);
        boolean result = imageUpload.execute().get();
        // 업로드된 이미지 json 추가
        imageFileJsonObj.put("imageFile" + (i + 1), fileName);
        // 전자서명을 위하여 해쉬값 추가
        hashValue.append(createHashValue(imageFile));

        // 맨 뒤에는 구분자 넣지 않음
        if ((i + 1) < imagePathList.size()) {
          hashValue.append("^");
        }

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

    } catch (Exception e) {
      e.printStackTrace();
    }

    String userId = Util.getStringPreference(mContext, "userInfo", "userId");
    String certResult = SignWrapper.getInstance().signData(userId, hashValue.toString());


    saveData.put("certResult", certResult);
    saveData.put("certTarget", hashValue.toString());
    saveData.put("fileSize", imageFileSize);
    saveData.put("imageFileJson", imageFileJsonObj.toString());

    return saveData;
  }

  /**
   * 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 Util.sha256(null, fileBuf);
  }

  @Override
  public void result(SoapObject result) {
    Log.e(TAG, "result !!  -- > " + result);
    if (result == null) {
      stop();
    } else {
      String res = result.getProperty("responseData").toString().trim();
      int intRes = Integer.parseInt(res);

      if (intRes == -1) {
        stop();
      } else {
        String pid = saveMapData.get("patientCode").toString();
        String inDd = saveMapData.get("clnDate").toString();
        if (instance.consentCenterAdaper != null) {
          instance.centerMenu.getConsentList(pid, inDd);
        }

        if (!apiType.equals("")) {
          if (!apiType.equals("centerTemp")) {
            instance.history.getHistoryConsentList(apiType);
          }
        }

        eFormToolkit.sendEFormViewerOkEvent();
      }
    }

  }

  @Override
  public void stop() {
    String msg = "";
    if (buttonType.equals(ResultCode.SAVE.toString())) {
      msg = mContext.getString(R.string.cert);
    } else if (buttonType.equals(ResultCode.TEMP_SAVE.toString())) {
      msg = mContext.getString(R.string.temp);
    } else if (buttonType.equals(ResultCode.TEMP_SAVE2.toString())) {
      msg = mContext.getString(R.string.confirm);
    }

    eFormToolkit.sendEFormViewerCancelEvent(String.format(mContext.getString(R.string.saveFailed), msg));
  }

  @Override
  public void error() {

  }
}

