package jp.agentec.abook.abv.ui.common.constant;

import jp.agentec.abook.abv.bl.common.exception.ABVException;
import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode;
import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.log.LogLevel;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.adf.util.StringUtil;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.widget.Toast;

public class ErrorMessage {

	/**
	 * ErrorCodeからリソース文字列を取得する
	 * 
	 * @param context
	 * @param errorCode
	 * @return
	 */
	public static String getMessageByErrorCode(Context context, ErrorCode errorCode) {
		return context.getResources().getString(errorCode.resId);
	}

	/**
	 * エラーメッセージを取得する
	 * 
	 * @param context
	 * @param error ErrorCode/ABVExceptionCode/String(ErrorCodeの文字列)/Exception
	 * @return
	 */
	public static String getErrorMessage(Context context, Object error) {
		if (error instanceof ErrorCode) {
			ErrorCode errorCode = (ErrorCode)error;
			//ログレベルがデバッグじゃないと予想以外のエラーは表示しなしC_E_SYSTEM_0001
			if (context.getResources().getInteger(R.integer.log_level) > LogLevel.debug.level()
					&& (errorCode .equals(ErrorCode.E107) || errorCode.equals(ErrorCode.C_E_SYSTEM_0001) || errorCode.equals(ErrorCode.ERROR))) {
				return null;
			}
			return getMessageByErrorCode(context,errorCode);
		}
		else if (error instanceof ABVExceptionCode) {
			ErrorCode errorCode = convertErrorCode(((ABVExceptionCode)error).name());
			if (errorCode != null) {
				return getMessageByErrorCode(context,errorCode);
			}
		}
		else if (error instanceof String) {
			ErrorCode errorCode = convertErrorCode((String) error);
			if (errorCode != null) {
				return getMessageByErrorCode(context,errorCode);
			}
			return (String)error;
		}
		else if (error instanceof NetworkDisconnectedException) {
			return getErrorMessage(context, ErrorCode.NETWORK);
		}
		else if (error instanceof AcmsException) {
			String msg = ((AcmsException) error).getLoginErrorMessage();
			if (StringUtil.isNullOrEmpty(msg)) {
				msg = ((AcmsException) error).getMessage();
			}
			if (StringUtil.isNullOrEmpty(msg)) { // TODO: ABook+にも適用
				ABVExceptionCode exceptionCode = ((AcmsException) error).getCode();
				if (exceptionCode != null) {
					ErrorCode errorCode = convertErrorCode(exceptionCode.name());
					if (errorCode != null) {
						msg = getMessageByErrorCode(context,errorCode);
					}
				}
			}
			return msg;
		}
		else if (error instanceof Exception) {
			return ((Exception) error).getMessage();
		}
		else if (error instanceof Integer) {
			return context.getResources().getString((Integer)error);
		}
		return null;
	}

	/**
	 * ABVExceptionからErrorCodeを取得する。
	 * 該当ない場合、ABVExceptionCodeを返す。
	 * 
	 * @param e
	 * @return
	 */
	public static Object getErrorCode(ABVException e) {
		if (e == null) {
			return ErrorCode.ERROR;
		}
		
		ErrorCode errorCode = convertErrorCode(e.getCode().name());
		if (errorCode != null) {
			return errorCode;
		}
		
		return e.getCode();
	}
	
	/**
	 * ABVExceptionCodeをErrorCodeに変換する
	 * 
	 * @param codeName
	 * @return
	 */
	public static ErrorCode convertErrorCode(String codeName) {
		ErrorCode[] searchedArray = new ErrorCode[]{
				ErrorCode.C_E_SYSTEM_0001,
				ErrorCode.C_E_SYSTEM_0002,
				ErrorCode.C_E_SYSTEM_0003,
				ErrorCode.C_E_SYSTEM_0004,
//				ErrorCode.C_E_SYSTEM_0101,
//				ErrorCode.C_E_SYSTEM_0102,
//				ErrorCode.C_E_SYSTEM_0103,
				ErrorCode.C_E_SECURITY_1001,
				ErrorCode.C_E_SECURITY_1002,
				ErrorCode.C_E_SECURITY_1003,
				ErrorCode.C_E_SECURITY_1004,
				ErrorCode.C_E_SECURITY_1005,
//				ErrorCode.C_E_SECURITY_1006,
//				ErrorCode.C_E_CONTENT_1001,
//				ErrorCode.C_E_CONTENT_1002,
//				ErrorCode.C_E_CONTENT_1003,
//				ErrorCode.C_E_CONTENT_1004,
				ErrorCode.C_I_CONTENT_0001,
				ErrorCode.C_I_CONTENT_0002,
				ErrorCode.C_W_SYSTEM_0001,
				ErrorCode.S_E_ACMS_0001,
				ErrorCode.S_E_ACMS_0400,
				ErrorCode.S_E_ACMS_0403,
				ErrorCode.S_E_ACMS_0404,
				ErrorCode.S_E_ACMS_0500,
				ErrorCode.S_E_ACMS_INVALID_RESPONSE,
				ErrorCode.S_E_ACMS_1403,
				ErrorCode.S_E_ACMS_L001,
				ErrorCode.S_E_ACMS_L002,
				ErrorCode.S_E_ACMS_L004,
				ErrorCode.S_E_ACMS_L005,
				ErrorCode.S_E_ACMS_L006,
				ErrorCode.S_E_ACMS_L008,
				ErrorCode.S_E_ACMS_L009,
				ErrorCode.S_E_ACMS_L010,
				ErrorCode.S_E_ACMS_L012,
				ErrorCode.E129,
		};
		for (int i = 0; i < searchedArray.length; i++) {
			if (searchedArray[i].name().equals(codeName)) {
				return searchedArray[i];
			}
		}
		return null;
	}
	
	/**
	 * エラーメッセージを取得して、Toast表示する
	 * 
	 * @param context
	 * @param error
	 */
	public static void showErrorMessageToast(Context context, final Object error) {
		String messgage = getErrorMessage(context, error);
		if (messgage != null) {
			showErrorMessageToast(context, messgage);
		}
	}
	
	/**
	 * メッセージをToast表示する
	 * 
	 * @param context
	 * @param messgage
	 */
	public static void showErrorMessageToast(final Context context, String messgage) {
		ABVToastUtil.showMakeText(context, messgage, Toast.LENGTH_LONG);
	}
	
	public static void showNetworkErrorMessageToast(final Context context) {
		showErrorMessageToast(context, ErrorCode.NETWORK);
	}

	public static void showErrorMessageDialog(final Context context,final int title, final ErrorCode errorCode) {
		showErrorMessageDialog(context, title, errorCode, null);
	}
	
	public static void showErrorMessageDialog(final Context context,final int title, final ErrorCode errorCode, OnClickListener listener) {
		ABookAlertDialog builder = AlertDialogUtil.createAlertDialog(context, title);
		builder.setMessage(getMessageByErrorCode(context, errorCode));
		builder.setNegativeButton(R.string.ok, listener);
		builder.show();
	}

}
