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

import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.acms.client.json.AcmsMessageJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.AppLastVersionParameters;
import jp.agentec.abook.abv.bl.acms.type.AcmsApis;
import jp.agentec.abook.abv.bl.acms.type.AuthLevel;
import jp.agentec.abook.abv.bl.acms.type.LoginMode;
import jp.agentec.abook.abv.bl.acms.type.ServiceOption.ServiceOptionId;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.Callback;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.exception.ABVException;
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.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic;
import jp.agentec.abook.abv.cl.environment.NetworkAdapter;
import jp.agentec.abook.abv.cl.push.FcmManager;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.UserPrefKey;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
import jp.agentec.abook.abv.ui.common.constant.NaviConsts;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.helper.ABVViewUnbindHelper;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.home.activity.LoginActivity;
import jp.agentec.abook.abv.ui.home.activity.OperationListActivity;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.FileUtil;
import jp.agentec.adf.util.StringUtil;

public abstract class ABVNoAuthenticatedActivity extends ABVActivity {
	private static final String TAG = "ABVNoAuthenticatedActivity";

    private Context mContext = ABVNoAuthenticatedActivity.this;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		setPortraitIfNormal();
	}

	@Override
	protected void onStop() {
		super.onStop();
		ABVViewUnbindHelper.unbindReferences(getContentViewId());
	}
	
	protected abstract View getContentViewId();
	
	/**
	 * メイン画面の表示
	 * 
	 * @param loginId
	 */

	protected void showMainActivity(String loginId) {
		startActivity(new Intent().setClassName(getApplicationContext().getPackageName(), getMainActivityClassName()).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), NaviConsts.Right);
		finish();
		Intent intent = new Intent();
		getApplicationContext().sendBroadcast(intent);
	}
	
	// ログインなしの場合専用
	protected void noAuthenticatedLogin(final boolean isGuestLogin, final String urlPath) {
		CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
				final Callback resultCallback = new Callback() {
					@Override
					public Object callback(Object ret) {
						String fcmToken = (String)ret;
						if (fcmToken == null) {
							ABVToastUtil.showMakeText(mContext, R.string.fcm_not_supported, Toast.LENGTH_SHORT);
							// FCMトークンを取得できない場合、noneIdでセットしてログインする
							fcmToken = "noneId";
						}
						noAuthenticatedShowMain(isGuestLogin, fcmToken, urlPath);
						return null;
					}
				};
                FcmManager.getFcmToken(mContext, resultCallback);
            }
        });
	}

	protected void noAuthenticatedShowMain(boolean isGuestLogin, String deviceToken, String urlPath) {
		try {
			
			SharedPreferences pref = getSharedPreferences(AppDefType.PrefName.USER_PREFERENCE, Context.MODE_PRIVATE);
			pref.edit().putBoolean(AppDefType.UserPrefKey.GUEST_LOGIN, isGuestLogin).commit();
			
			// Wifi接続の確認
			String loginId = UUID.randomUUID().toString();

			NetworkAdapter na = NetworkAdapter.getInstance();
			boolean network_conn = na.isNetworkConnected();
			if (network_conn) {
				// ym.chae
				// 初回ログインの場合、任意のID＆PWDを生成してサーバへ登録する
				UserAuthenticateLogic userAuthenticateService = AbstractLogic.getLogic(UserAuthenticateLogic.class);
				if (urlPath == null) {
					urlPath = getResources().getString(R.string.account_path);
				}
				String password = "password";
				Logger.d("UUID 테스트", "UUID 테스트 : " + loginId);
				userAuthenticateService.noAuthenticatedLogin(urlPath, loginId, password, deviceToken, isGuestLogin);
				startLogoAnimation();
			} else {
				ABookAlertDialog messageDialog = AlertDialogUtil.createAlertDialog(mContext, R.string.app_name);
				messageDialog.setMessage(R.string.NETWORK);
				messageDialog.setPositiveButton(R.string.confirm, new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int whichButton) {
						finish();
					}
				});
				messageDialog.show();
			}

		} catch (final NetworkDisconnectedException e) {
			Logger.e(TAG, "NetworkDisconnectedException", e);
			showErrorDialog(e);
		} catch (final Exception e) {
			Logger.e(TAG, "noAuthenticatedShowMain error.", e);
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					showErrorDialog(e);
				}
			});
		}
	}

	protected void showErrorDialog(Exception e) {
		final ABookAlertDialog messageDialog = AlertDialogUtil.createAlertDialog(mContext, R.string.app_name);
		String message;
		if (e instanceof NetworkDisconnectedException) {
			message = getString(R.string.NETWORK);
		}
		else if (e instanceof ABVException) {
			if (e.getCause() != null && e.getCause() instanceof AcmsException) {
				message = ErrorMessage.getErrorMessage(this, e.getCause());
			}
			else {
				message = getString(R.string.ERROR);
			}
		}
		else {
			message = getString(R.string.ERROR);
		}
		messageDialog.setMessage(message);
		messageDialog.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
			@Override
            public void onClick(DialogInterface dialog, int whichButton) {
				messageDialog.dismiss();
			}
		});
		messageDialog.show();
	}

	/**
	 * 起動画面のアニメーション処理
	 */
	protected void startLogoAnimation() {
		final ImageView v = (ImageView) findViewById(R.id.img_logo);
		final AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f);
		animation.setDuration(2000);
		animation.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
			}
			@Override
			public void onAnimationRepeat(Animation animation) {
			}
			@Override
			public void onAnimationEnd(Animation animation) {
				v.setVisibility(View.INVISIBLE);
				showMain();
			}
		});
		handler.post(new Runnable() {
			@Override
			public void run() {
				v.startAnimation(animation);
			}
		});
	}

	private void showMain() {
				try {
					try {
						final ABVDataCache dataCache = ABVDataCache.getInstance();
						dataCache.refreshServiceOptions();
						
						// アプリのバージョンを確認する
						final ABVEnvironment abvEnvironment = ABVEnvironment.getInstance();
						if (isNeedCheckNewAppVersion()) {

                            final Callback resultCallback = new Callback() {
                                @Override
                                public Object callback(Object ret) {
                                    boolean isSelectedOK = (boolean)ret;
                                    if (isSelectedOK) {
                                        PreferenceUtil.removeUserPref(ABVNoAuthenticatedActivity.this, UserPrefKey.CHECK_NEW_VERSION_DATE);
                                        //App強制終了
                                        android.os.Process.killProcess(android.os.Process.myPid());
                                    } else {
										moveToHome();
                                    }
                                    return null;
                                }
                            };
                            //パーミッションチェック
                            ABookPermissionHelper helper = new ABookPermissionHelper(this, Constant.ABookPermissionType.ReadExternalStorage, resultCallback);
                            if (helper.checkMultiPermissions(true)) {
                                // showAlert
                                ABookAlertDialog dialog = AlertDialogUtil.createABookAlertDialog(mContext);
                                dialog.setTitle(R.string.app_update);
                                dialog.setMessage(R.string.need_to_application_update);
                                dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        // バージョンアップフラグをON
                                        PreferenceUtil.put(getApplicationContext(), AppDefType.DefPrefKey.APP_VERSIONUP_PROCESSING, true);

                                        // Download 開始
                                        DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                                        String currentDate = DateTimeUtil.toString(DateTimeUtil.getCurrentTimestamp(), DateTimeFormat.yyyyMMddHHmmss000_none);
                                        String downloadUrl = AcmsApis.getDownloadApplicationFileUrl(abvEnvironment.acmsAddress, dataCache.getUrlPath(), dataCache.getMemberInfo().sid, currentDate);
                                        Logger.d(TAG, "downloadUrl=%s", downloadUrl);
                                        Request request = new Request(Uri.parse(downloadUrl));
                                        request.setDescription("ABook Plus New Version File");
                                        //LANケーブル接続のタイプ(ETHERNET TYPE)がないため、セットしない
//									request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
                                        File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ABVEnvironment.APK_FILE_NAME);
                                        Logger.d(TAG, "download local file=%s", file.getAbsolutePath());
                                        File[] childs = file.getParentFile().listFiles();
                                        if (childs != null && childs.length > 0 && childs[0].exists()) {
                                            childs[0].delete();
                                        }
                                        request.setDestinationUri(Uri.fromFile(file));
                                        downloadManager.enqueue(request);

										if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
											registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), RECEIVER_NOT_EXPORTED);
										} else {
											registerReceiver(new OnAppDownloadReceiver(), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
										}

										// アプリを閉じる
                                        saveLeaveAppTime();
                                        moveTaskToBack(true);
                                    }
                                });
                                dialog.setNegativeButton(R.string.cancel, new OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
										moveToHome();
                                    }
                                });
                                showAlertDialog(dialog);
                            } else {
                                Logger.w(TAG,"ReadExternalStorage checkMultiPermissions false");
                            }

						} else {
							moveToHome();
						}
					} catch (Exception e) {
						// ignore
						moveToHome();
					}
				} catch (Exception e) {
					Logger.e("ABVException Login", e);
					Intent intent = new Intent();
					intent.setClassName(getApplicationContext().getPackageName(), LoginActivity.class.getName()).setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
					startActivity(intent);
					finish();
				}
	}



	/**
	 * １日１回のバージョンチェックを行う
	 * @return true チェックを行う false 行わない
	 * @throws NetworkDisconnectedException 
	 * @throws AcmsException 
	 */
	private boolean isNeedCheckNewAppVersion() throws AcmsException, NetworkDisconnectedException {
		long checkedDateValue = getUserPref(UserPrefKey.CHECK_NEW_VERSION_DATE, -1L);
		Date currentDate = DateTimeUtil.formatDate(DateTimeUtil.getCurrentDate(), DateTimeFormat.yyyyMMdd_none);
		
		boolean isNeedCheck = false;
		if (checkedDateValue == -1) {
			isNeedCheck = true;
		} else {
			Date checkedDate = DateTimeUtil.formatDate(new Date(checkedDateValue), DateTimeFormat.yyyyMMdd_none);
			Logger.d(TAG, "checkedDate=%s", checkedDate.toString());
			Logger.d(TAG, "currentDate=%s", currentDate.toString());
			if (checkedDate.before(currentDate)) {
				isNeedCheck = true;
			}
		}

		if (isNeedCheck) {
			final ABVDataCache dataCache = ABVDataCache.getInstance();
			final ABVEnvironment abvEnvironment = ABVEnvironment.getInstance();
			AppLastVersionParameters param;
			// 既にMacAddress使用に同意している場合はMacAddressを使う
			if (ABVEnvironment.getInstance().deviceIdType == Constant.DeviceIdType.MAC_ADDRESS) {
				param = new AppLastVersionParameters(dataCache.getMemberInfo().sid, abvEnvironment.appVersion, String.valueOf(ABVEnvironment.AppId), null, abvEnvironment.deviceId);
			} else {
				param = new AppLastVersionParameters(dataCache.getMemberInfo().sid, abvEnvironment.appVersion, String.valueOf(ABVEnvironment.AppId), abvEnvironment.deviceId, null);
			}

			final String version = AcmsClient.getInstance(ABVDataCache.getInstance().getUrlPath(), ABVEnvironment.getInstance().networkAdapter).appLatestVersion(param);
			Logger.d(TAG, "Last Version=%s, Current Version=%s", version, ABVEnvironment.getInstance().appVersion);
			if (version != null && version.length() > 0) {
				if (version.equals(ABVEnvironment.getInstance().appVersion) == false) {
					// アラート表示は1日1回であるため、trueになった場合、チェック日付を保存しておく
					PreferenceUtil.putUserPref(this, UserPrefKey.CHECK_NEW_VERSION_DATE, currentDate.getTime());
				} else {
					isNeedCheck = false;
				}
			} else {
				isNeedCheck = false;
			}
			
		}
		// ストアバージョンの場合、チェックのみを行う
		if (getRBoolean(R.bool.store_version)) {
			return false;
		}

		return isNeedCheck;
	}

	protected void moveToHome() {
		try {
			Bundle extras = getIntent().getExtras();
			Intent intent = new Intent();
			if (extras != null && !StringUtil.isNullOrEmpty(extras.getString(AppDefType.PushMessageKey.data))) {
				intent.putExtra(AppDefType.PushMessageKey.data, extras.getString(AppDefType.PushMessageKey.data));
			}

			// 定期点検用
            if (extras != null && !StringUtil.isNullOrEmpty(extras.getString(AppDefType.PushMessageKey.operationId))) {
                intent.putExtra(AppDefType.PushMessageKey.operationId, extras.getString(AppDefType.PushMessageKey.operationId));
                intent.putExtra(AppDefType.PushMessageKey.message, extras.getString(AppDefType.PushMessageKey.message));
            }
			intent.setClassName(getApplicationContext().getPackageName(), getMainActivityClassName()).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			final Uri data = getIntent().getData();
			Logger.i(TAG, "call from URI intent : %s", data);
			if (data != null && data.getScheme() != null) {
				if (data.getScheme().equals(getString(R.string.scheme_url))) { // カスタムURI
					intent.putExtra(CID, getLongValFromURI(data, CID));
					intent.putExtra(PAGE, (int)getLongValFromURI(data, PAGE));
					intent.putExtra(URL, getValFromURI(data, URL)); // Reader
					intent.putExtra(PASSWORD, getValFromURI(data, PASSWORD)); // Reader
					intent.putExtra(MESSAGE, getValFromURI(data, MESSAGE)); // Reader
				}
			}
			startActivity(intent);
			finish();
		} catch (Exception e) {
			Logger.e("ABVException Login", e);
			Intent intent = new Intent();
			intent.setClassName(getApplicationContext().getPackageName(), LoginActivity.class.getName()).setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
			startActivity(intent);
			finish();
		}
	}

	/**
	 * カスタムURL対応
	 * @param uri 
	 * 
	 * @return long値
	 */
	private long getLongValFromURI(Uri uri, String key) {
		String val = uri.getQueryParameter(key);
		Logger.d(TAG, "call from uri %s : %s", key, val);
		try {
			return Long.valueOf(val).longValue();
		} catch (Exception e) {
			Logger.w(TAG, e.toString()); // ignore
		}
		return 0;
	}

	/**
	 * カスタムURL対応 
	 * 
	 * @param uri
	 * @return val
	 */
	private String getValFromURI(Uri uri, String key) {
		String url = uri.getQueryParameter(key);
		Logger.d(TAG, "call from uri %s : %s", key, url);
		return url;
	}
	
	protected String getMainActivityClassName() {
		return OperationListActivity.class.getName();
	}

	protected abstract void goNext();
}
