package com.dbs.mplus.fatima.processor;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.webkit.WebView;
import android.widget.EditText;

import com.dbs.mplus.fatima.consent.ConsentFacade;
import com.dbs.mplus.fatima.consent.sign.BatchSignTask;
import com.dbs.mplus.fatima.consent.sign.SignWrapper;
import com.dbs.mplus.fatima.consent.webservice.ConsentWSWrapper;
import com.dbs.mplus.fatima.framework.MPlusFrameworkConstants;
import com.dbs.mplus.fatima.framework.processor.MPlusMessageProcessor;
import com.dbs.mplus.fatima.framework.processor.msg.ConsentMessage;
import com.dbs.mplus.fatima.framework.processor.msg.ConsentSignMessage;
import com.dbs.mplus.fatima.framework.processor.msg.Message;
import com.dbs.mplus.fatima.framework.util.MPlusLogUtil;
import com.dbs.mplus.fatima.framework.util.MPlusStringUtil;
import com.dbs.mplus.fatima.MPlusApplication;
import com.dbs.mplus.fatima.MPlusConstants;
import com.dbs.mplus.fatima.framework.view.dialog.MPlusDialog;
import com.dbs.mplus.fatima.util.IntentUtil;
import com.lumensoft.ks.KSException;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import kr.co.clipsoft.eform.EFormToolkit;

/**
 * 서버에서 수신된 메시지를 처리한다.
 *
 * @author hyeeun
 */
public class MessageProcessor extends MPlusMessageProcessor {

	private ConsentFacade consentFacade;

	/**
	 * 생성자 
	 * @param activity
	 * @param webView
	 * @param jsonStr
	 */
	public MessageProcessor(Activity activity, WebView webView, String jsonStr) { 
		super(activity, webView, jsonStr);

		this.consentFacade = new ConsentFacade(activity, webView);
	}
	
	/**
	 * 기본 브라우징 
	 * @param msg
	 */
	@Override
	protected void processBrowsing(Message msg) { 
        final String key = MPlusFrameworkConstants.MSG_VALUE_KEY.BROWSING_URL.toString();
        final String url = msg.getValueMap().get(key); 

        final Intent intent = IntentUtil.getBrowsingIntent(this.activity, url); 
        this.activity.startActivity(intent);		
	}
	
	/**
	 * 팝업브라우징  (본인인증 시작) 
	 * @param msg
	 */
	@Override
	protected void processAuthPopupBrowsing(Message msg) {
        final String key = MPlusFrameworkConstants.MSG_VALUE_KEY.BROWSING_URL.toString();
        final String url = msg.getValueMap().get(key);            	
    	final Intent intent = IntentUtil.getAuthPopupBrowsingIntent(this.activity, url);
    	this.activity.startActivity(intent); 		
	}
	
    /**
     * 앱 종료 
     * @param msg
     */
	@Override
	protected void processAppExit(Message msg) {
    	final MPlusApplication app = (MPlusApplication) this.activity.getApplication();

        // 앱 종료시 캐쉬 정리 - 쿠키는 정리하지 않음
        this.webView.clearCache(true);
		this.webView.clearHistory();

    	// 현재 activity 종료 
    	this.activity.moveTaskToBack(true); 
    	this.activity.finish();

    	// 홈 화면 불러주고 
    	app.startActivity(IntentUtil.getHomeIntent());
	}

	@Override
	protected void processVersion(Message msg) {
		final String callBackName = msg.getValueMap().get(MPlusFrameworkConstants.MSG_VALUE_KEY.CALLBACK_FN.toString());
		StringBuilder builder = new StringBuilder();

        // 패키지 버전 가져와서 붙이고
        try {
            PackageInfo info = this.activity.getPackageManager().getPackageInfo(this.activity.getPackageName(), PackageManager.GET_META_DATA);
            builder.append("V").append(info.versionName);
            // ex : Debug mode, Release mode
            if(MPlusFrameworkConstants.DEBUG_MODE) {
                builder.append("D");
            }
            else {
                builder.append("R");
            }
        }
        catch(Exception ex) {
            // 무시
        }

        // ex : 19
        builder.append("-").append(Build.VERSION.SDK_INT);

        // 결과 정리
		final String script = MPlusStringUtil.getCallbackFnString(callBackName, builder.toString());
		// 결과 불러주기
		this.webView.loadUrl(script);
	}

    @Override
    protected void processExtraPopupBrowsing(Message msg) {
        // 열어 볼 주소
        final String url = msg.getValueMap().get(MPlusFrameworkConstants.MSG_VALUE_KEY.BROWSING_URL.toString());
        final Intent intent = IntentUtil.getExtraPopupBrowsingIntent(this.activity, url);
        this.activity.startActivity(intent);
    }

	/**
     * 전자동의서 호출
     */
	@Override
	protected void processConsentReq(Message msg) {
		// 전자 동의서 호출됨
		MPlusLogUtil.DEBUG(this.getClass(), "동의서띄우기 메시지 받음: " + msg);
		if(msg instanceof ConsentMessage) {
			ConsentMessage consentMsg = (ConsentMessage)msg;
			this.consentFacade.startConsent(consentMsg);
		}
	}

	/**
	 * 동의서 전자서명
	 * @param msg
     */
	@Override
	protected void processConsentSignReq(Message msg) {
		// 전자 동의서 호출됨
		MPlusLogUtil.DEBUG(this.getClass(), "동의서 전자서명 요청 받음: " + msg);
		if(msg instanceof ConsentSignMessage) {
			ConsentSignMessage signMessage = (ConsentSignMessage) msg;
			String userId = signMessage.getUserId();
			if(SignWrapper.getInstance().isCertificate(userId)) {
				try {
					boolean result = new BatchSignTask(signMessage).execute().get();
					this.callbackSignData(signMessage, result, result ? null : "일괄인증에 실패 했습니다.");
				} catch (Exception e) {
					e.printStackTrace();
					this.callbackSignData(signMessage, false, e.getMessage());
				}
			} else {
				// 인증서 인증시작
				startCertificate(signMessage, this.activity, userId);
			}
		}
	}

	/**
	 *
	 * @param context
	 * @param userId
	 */
	private void startCertificate(final ConsentSignMessage signMessage, final Context context, final String userId) {
		final EditText passwordEdit = new EditText(context);
		passwordEdit.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
		passwordEdit.setTransformationMethod(PasswordTransformationMethod.getInstance());

		DialogInterface.OnClickListener okListener = new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				String password = passwordEdit.getText().toString();
				MPlusLogUtil.DEBUG(this.getClass(), "비밀번호 입력 확인:" + password);
				try {
					// 인증서 인증
					if(SignWrapper.getInstance().certificate(context, userId, password)) {
						Boolean result = new BatchSignTask(signMessage).execute().get();
						callbackSignData(signMessage, result, result ? null : "일괄인증에 실패 했습니다.");
					} else {
						MPlusDialog.getOKDialog(context, "인증서 입력-" + userId, "인증서 암호가 올바르지 않습니다.", null).show();
					}
				} catch (Exception e) {
					e.printStackTrace();
					MPlusDialog.getOKDialog(context, "인증서 입력-" + userId, e.getMessage(), null).show();
				}
			}
		};
		DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			}
		};
		AlertDialog dialog = MPlusDialog.getPasswordInputDialog(context, "인증서 입력-" + userId, "인증서 암호를 입력하세요", okListener, cancelListener);
		dialog.setView(passwordEdit);
		dialog.show();
	}

	private void callbackSignData(Message message, boolean success, String errorMsg) {
		String callbackFunction = message.getValueMap().get(MPlusFrameworkConstants.MSG_VALUE_KEY.CALLBACK_FN.toString());
		JSONObject result = new JSONObject();
		JSONObject resultCode = new JSONObject();
		try {
			resultCode.put("resultCode", success ? 200 : 400);
			resultCode.put("errorMsg", errorMsg);
			result.put("result", resultCode);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		this.webView.loadUrl(MPlusStringUtil.getCallbackFnString(callbackFunction, result.toString()));
	}

}
