package com.dbs.mplus.fatima.consent;

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

import com.dbs.mplus.fatima.R;
import com.dbs.mplus.fatima.activity.ConsentActivity;
import com.dbs.mplus.fatima.consent.sign.SignWrapper;
import com.dbs.mplus.fatima.httpTask.HttpCallBack;
import com.dbs.mplus.fatima.httpTask.HttpImageUpload;
import com.dbs.mplus.fatima.util.ConsentConfig;
import com.dbs.mplus.fatima.util.Util;

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.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

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> {

  private static final String TAG = "EFormSaveHandler";
  private Context mContext;
  private EFormToolkit eFormToolkit;
  private HashMap<String, Object> consentData;
  private ConsentActivity instance;
  private HashMap<String, Object> saveData = null;

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

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

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

  private void saveProcess(HashMap saveData, ResultEventArgs eventArgs) {
    buttonType = eventArgs.getResultCode().toString();

    if (Util.checkNetwork(mContext) != true) {
      eFormToolkit.sendEFormViewerCancelEvent(mContext.getString(R.string.networkError));
    } else {

      int state = 0;
      String consentState = "";
      Log.e(TAG, "buttonType -- > " + buttonType);
      if (buttonType.equals("SAVE")) {
        consentState = ConsentConfig.CERTIFY_CMP;
      } else if (buttonType.equals("TEMP_SAVE")) {
        consentState = ConsentConfig.TEMP;
      }

//      try {
//        HashMap<String, String> mData = new HashMap<String, String>();
//        mData.put("consentmstrid", saveData.get("consentMstRid").toString());
//        mData.put("consent_state", consentState);
//        HttpSoapConnection connection = new HttpSoapConnection(ConsentConfig.HOST_CONSENT, ConsentConfig.CHECK_CONSENT_STATE, mData);
//        SoapObject object = connection.execute().get();
//        state = Integer.parseInt(object.getProperty("CheckConsentState").toString().trim());
//
//      } catch (ExecutionException e) {
//        e.printStackTrace();
//      } catch (InterruptedException e) {
//        e.printStackTrace();
//      } catch (NullPointerException e) {
//        e.printStackTrace();
//      }

      if (state == 1) {
        eFormToolkit.sendEFormViewerCancelEvent(mContext.getString(R.string.writeConsnet));
        return;
      }

      switch (eventArgs.getResultCode()) {
        case SAVE:
          saveData.putAll(imageUpload(eventArgs, saveData.get("userId").toString()));
//          Util.LOG(EFormSaveHandler.class, "saveData -- > " + saveData);

          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_COMPLETE_ALL, saveData, callBack);
          break;
        case TEMP_SAVE:
//          Util.LOG(EFormSaveHandler.class, "saveData -- > " + saveData);
          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_TEMP_DATA, saveData, callBack);
//          Util.callHttp(mContext, ConsentConfig.HOST_CONSENT, ConsentConfig.SAVE_TEMP_DATA, saveData, callBack);
//          HttpCon httpCon = new HttpCon("http://172.16.10.192/ConsentSvc.asmx", saveData);
//          try {
//            String result = httpCon.execute().get();
//
//            JSONObject object = Util.xmltoJsonObject(result);
//            String res = Util.xmlToJsonString(object);
//            Log.e(TAG, "res -- > " + res);
//
//          } catch (ExecutionException e) {
//            e.printStackTrace();
//          } catch (InterruptedException e) {
//            e.printStackTrace();
//          }
//          eFormToolkit.sendEFormViewerOkEvent();
          break;
      }

    }
  }

  private HashMap<String, Object> createSaveData(ResultEventArgs eventArgs, HashMap<String, Object> consentData) {
    HashMap<String, Object> resultMap = new HashMap<String, Object>();

    int index = eventArgs.getFormOpenSequence() - 1;
    HashMap<String, String> globalParam = (HashMap<String, String>) consentData.get("globalParam");
    ArrayList<HashMap<String, String>> formListParam = (ArrayList<HashMap<String, String>>) consentData.get("consentParam");
    HashMap<String, String> formParam = (HashMap<String, String>) formListParam.get(index);

    String userId = globalParam.get("userid");
    String patientCode = formParam.get("IO_Pt_ID");
    String clnDeptCode = formParam.get("IO_DeptCd");
    String formRid = formParam.get("formRid");
    String formCd = formParam.get("formCd");
    String consentMstRid = (formParam.get("rid") == null ? "-1" : formParam.get("rid"));
    String rewriteConsentMstRid = "0";
    String dataXml = eventArgs.getDataXml();
    String deviceType = "AND";
    String deviceIdentNo = Util.getMACAddress();
    String vistType = globalParam.get("visitType");
    String hosType = "111";
    String clnDate = formParam.get("IO_ADdate");
    String ward = formParam.get("ward");
    String roomcd  = formParam.get("roomNo");
    String orderNo = formParam.get("orderNo") == null || formParam.get("orderNo").equals("") ? "0" : formParam.get("orderNo");
    String orderName = formParam.get("IO_Dx");
    String orderCd = formParam.get("orderCd") == null ? "" : formParam.get("orderCd");
    String ocrCode = formParam.get("IO_ocr_cd");
    String cretno = formParam.get("hospitalCretno") == null ? "0" : formParam.get("hospitalCretno");
    String createUserName = formParam.get("IO_INPUTNM");
    String modifyUserName = formParam.get("IO_INPUTNM");
    String dschdd = formParam.get("outDate");
    String mainDrId = formParam.get("mainDrId");

    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("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());
    try {
      resultMap.put("dataXml", Util.base64Encode(dataXml));
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    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("dschdd", dschdd);
    resultMap.put("mainDrId", mainDrId);

    return resultMap;
  }

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

    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 certResult = SignWrapper.getInstance().signData(userId, hashValue.toString());

    saveData.put("certResult", certResult == null ? "" : certResult);
    saveData.put("certTarget", hashValue.toString());
//    saveData.put("fileSize", imageFileSize);
    saveData.put("consentState", ConsentConfig.CERTIFY_CMP);
    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);
  }

  private HttpCallBack callBack = new HttpCallBack() {
    @Override
    public void result(String result) {
      Log.e(TAG, "save result -- > " + result);
      if (buttonType.equals("TEMP_SAVE")) {
        if (result == null || result.equals("")) {
          stop();
        } else {
          JSONObject object = Util.xmltoJsonObject(result);
          String res = Util.xmlToJsonString(object);
          ArrayList<HashMap<String, String>> mapArrayList = Util.parseJSON(mContext, res);

          String rts = mapArrayList.get(0).get("SaveTempDataResult");
          if (rts.equals("0")) {
            stop();
          } else {
            String pid = saveData.get("patientCode").toString().trim();
            String indd = saveData.get("clnDate").toString().trim();
            if (instance.centerMenu != null) {
              if (!apiType.equals("write")) {
                instance.centerMenu.getConsentList(pid, indd);
              }

            }

          }

        }
      } else {
        if (result == null) {
          stop();
        } else {

          JSONObject object = Util.xmltoJsonObject(result);
          String res = Util.xmlToJsonString(object);
          ArrayList<HashMap<String, String>> mapArrayList = Util.parseJSON(mContext, res);

          String rts = mapArrayList.get(0).get("SaveCompleteAllResult");

          Log.e(TAG, "mapArrayList -- > " + mapArrayList);

          if (rts.equals("0")) {
            stop();
          } else {
            String pid = saveData.get("patientCode").toString().trim();
            String indd = saveData.get("clnDate").toString().trim();
            if (instance.centerMenu != null) {
              if (!apiType.equals("write")) {
                instance.centerMenu.getConsentList(pid, indd);
              }

            }

            if (apiType.equals("patient") || apiType.equals("write")) {
              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() {

    }
  };
}
