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

import android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;

import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
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.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.dto.MemberInfoDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ContractLogic;
import jp.agentec.abook.abv.bl.logic.UserAuthenticateLogic;
import jp.agentec.abook.abv.cl.helper.ABVUncaughtExceptionHandler;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.cl.util.RawResourceUtil;
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.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.helper.ProgressDialogHelper;
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.helper.ABookPermissionHelper;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;

public class ABookSettingFragment extends PreferenceFragment {
	private static final String TAG = "ABookSettingActivity";

	// Preferenceグループ
	private static final String ACCOUNT_SET = "account_set";
	private static final String LOG_INFO = "log_info";
	private static final String APP_INFO = "app_info";

	// アカウント
	private static final String ACCOUNT_PATH = "accountPath";
	private static final String LOGINID = "loginid";
	private static final String LAST_LOGIN = "lastLogin";
	private static final String PASSWORD_CHANGE = "passwordChange";
	private static final String LOGOUT = "logout";
	
	// ログ情報
	private static final String EXPORT = "export";
	
	// アプリ情報
	private static final String LICENSE_INFO = "licenseInfo";
	private static final String CHECK_APP_UPDATE = "checkAppUpdate";
	private static final String ABOUT_A_BOOK = "aboutABook";
	private static final String ABOOK_CHECK_MANUAL = "abookCheckManual";
	
	protected Handler handler = new Handler();
	protected AlertDialog alertDialog = null;

	// 機器連携（ペアリング）
	private static final String SET_CHINO_PAIRING = "setChinoPairing";		// CHINO機器
	private static final String SET_SPP_PAIRING = "setSppPairing";			// SPP通信機器

	private static final String OPERATION_SYNC_CATEGORY = "operation_sync_category";

	private PreferenceCategory operationSyncCategory;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		handler = new Handler();

		addPreferencesFromResource(R.xml.pref);
		operationSyncCategory = (PreferenceCategory) findPreference(OPERATION_SYNC_CATEGORY);
		applyOperationAutoSyncCategoryVisibility();
		// アカウント
		setAccountSetting();
		// ログ情報
		setLogInfoSetting();
		// アプリ情報
		setAppInfoSetting();

		// ペアリング設定
		setPairingSetting();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		return inflater.inflate(R.layout.setting_fragment, container, false);
	}

	@Override
	public void onResume() {
		super.onResume();
		applyOperationAutoSyncCategoryVisibility();
	}

	/**
	 * 事業者オプション187（自動同期）が CMS で Y のときのみ「自動同期」設定を表示する。
	 */
	private void applyOperationAutoSyncCategoryVisibility() {
		if (operationSyncCategory == null || getPreferenceScreen() == null) {
			return;
		}
		PreferenceScreen root = getPreferenceScreen();
		boolean show = ABVDataCache.getInstance().serviceOption.isEnterpriseAutoSyncOptionUsed();
		if (show) {
			if (operationSyncCategory.getParent() == null) {
				root.addPreference(operationSyncCategory);
			}
		} else {
			if (operationSyncCategory.getParent() != null) {
				root.removePreference(operationSyncCategory);
			}
		}
	}
    
	@Override
	public void onStart() {
		super.onStart();
	}

	private void setSummary(String key, String val) {
		PreferenceScreen prefScreen = (PreferenceScreen) findPreference(key);
		prefScreen.setSummary(val);
	}

	private void setAccountSetting() {
		PreferenceGroup accountSettings = (PreferenceGroup) findPreference(ACCOUNT_SET);
		PreferenceScreen logout = (PreferenceScreen) findPreference(LOGOUT);
		logout.setOnPreferenceClickListener(new OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				showLogoutAlert();
				return true;
			}
		});
		PreferenceScreen passwordChange = (PreferenceScreen) findPreference(PASSWORD_CHANGE);

		passwordChange.setOnPreferenceClickListener(new OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				// パスワード変更画面
				Intent intent = new Intent();
				String className = ChangePasswordActivity.class.getName();
				if (isNormalSize() == false) {
					className += "Dialog";
				}
				intent.setClassName(getActivity().getPackageName(), className);
				startActivity(intent);
				return true;
			}
		});

		MemberInfoDto dto = ABVDataCache.getInstance().getMemberInfo();
		// アカウント関連の設定
		//ドトールの場合：事業者とログインID非表示
		setSummary(LOGINID, dto.loginId);
		setSummary(ACCOUNT_PATH, AbstractLogic.getLogic(ContractLogic.class).getUrlPath());
		setSummary(LAST_LOGIN, DateTimeUtil.toString(dto.lastLoginDate, DateTimeFormat.yyyyMMddHHmmss_slash));
	}
	
	private void showLogoutAlert() {
		ABookAlertDialog logoutAkert = AlertDialogUtil.createAlertDialog(getActivity(), R.string.logout);
		logoutAkert.setMessage(R.string.logout_info);
		logoutAkert.setButton(DialogInterface.BUTTON_POSITIVE, getResources().getString(R.string.confirm), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				logout();
			}
		});
		logoutAkert.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.cancel), (DialogInterface.OnClickListener) null);
		showAlertDialog(logoutAkert);
	}

	private void logout() {
		try {
			// modify by Jang 2013.06.20
			UserAuthenticateLogic user = AbstractLogic.getLogic(UserAuthenticateLogic.class);
			// ログイン情報がある場合のみログアウト処理を行う
			if (user.getMemberInfo() != null) {
				user.signoutUser();
				// Widgetへ通知
				Intent intent = new Intent();
				getActivity().sendBroadcast(intent);
			}
		} catch (Exception e) {
			Logger.w("signoutUser failed at callLoginActivity", e);
			ABVToastUtil.showMakeText(getActivity(), R.string.ERROR, Toast.LENGTH_SHORT);
		}

		SharedPreferences sharedPreferences = getActivity().getSharedPreferences(AppDefType.PrefName.USER_PREFERENCE, Context.MODE_PRIVATE);
		sharedPreferences.edit().remove(AppDefType.UserPrefKey.GUEST_LOGIN).commit();

		Intent intent = new Intent(getActivity(), LoginActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
		startActivity(intent);

		getActivity().finish();

	}

	private void setLogInfoSetting() {
		PreferenceGroup logInfo = (PreferenceGroup) findPreference(LOG_INFO);
		// ログExport
		configureExportLog();
	}

	private void configureExportLog() {
		PreferenceScreen export = (PreferenceScreen) findPreference(EXPORT);
		export.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				try {
					ABVUncaughtExceptionHandler.getInstancer().showLogExportDialog(getActivity());
				} catch (Exception e) {
					Logger.e(TAG, "showBackupDialog", e);
					ABVToastUtil.showMakeText(getActivity(), R.string.ERROR, Toast.LENGTH_SHORT);
				}
				return true;
			}
		});
	}

	private void setAppInfoSetting() {
		PreferenceGroup appInfo = (PreferenceGroup) findPreference(APP_INFO);
		// ABookについて
		Preference aboutABook = findPreference(ABOUT_A_BOOK);
		aboutABook.setTitle(getResources().getString(R.string.about_app));
		aboutABook.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				showAboutABookDialog();
				return true;
			}
		});

		// ライセンス情報
		Preference licenseInfo = findPreference(LICENSE_INFO);
		licenseInfo.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				showLicenseDialog();
				return true;
			}
		});

		// アップデート確認
		Preference checkAppUpdate = findPreference(CHECK_APP_UPDATE);
		if (getResources().getInteger(R.integer.check_app_update) == 1) {
			checkAppUpdate.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
				@Override
				public boolean onPreferenceClick(Preference preference) {
					try {
						//パーミッションチェック
						ABookPermissionHelper helper = new ABookPermissionHelper(getActivity(), Constant.ABookPermissionType.ReadExternalStorage, null);
						if (helper.checkMultiPermissions(true)) {
							showCheckAppDialog();
						} else {
							Logger.w(TAG, "ReadExternalStorage checkMultiPermissions false");
						}
					} catch (Exception e) {
					}
					return true;
				}
			});
		} else {
			appInfo.removePreference(checkAppUpdate);
		}

		Preference abookCheckManual = findPreference(ABOOK_CHECK_MANUAL);

		// TODO マニュアルが古いので一旦非表示
		// 以下の処理が復活したら削除処理を消す
		appInfo.removePreference(abookCheckManual);

//		// リソースパターンの適用
//		abookCheckManual.setTitle(PatternStringUtil.patternToString(getActivity().getApplicationContext(),
//									R.string.operation_manual,
//									getUserPref(getActivity().getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
//		abookCheckManual.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
//			@Override
//			public boolean onPreferenceClick(Preference preference) {
//				try {
//					Intent intent = new Intent();
//					intent.putExtra(ABookKeys.CONTENT_ID, 0L);
//					intent.putExtra("FILEPATH", ABVEnvironment.getInstance().getContentCacheDirectoryPath(0L));
//					intent.putExtra("page", 0);
//					intent.setClass(getActivity(), GuideViewActivity.class);
//					startActivity(intent);
//				} catch (Exception e) {
//					Logger.e(TAG, e);
//				}
//				return true;
//			}
//		});
	}

	private void showLicenseDialog() {
		ProgressDialogHelper.showProgressPopup(getActivity(), true);
		CommonExecutor.execute(new Runnable() {
			@Override
			public void run() {
				final String msg = RawResourceUtil.readAsString(getActivity(), R.raw.license_abook);
				if (msg == null) {
					ABVToastUtil.showMakeText(getActivity(), R.string.E128, Toast.LENGTH_LONG);
					ProgressDialogHelper.closeProgressPopup();
					return;
				}

				handler.post(new Runnable() {
					@Override
					public void run() {
						ABookAlertDialog aBookAlertDialog = AlertDialogUtil.scrollableAlertDialog(getActivity(), R.string.licence_info, msg);
						aBookAlertDialog.setPositiveButton(R.string.ok, null);
						aBookAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
							@Override
							public void onShow(DialogInterface dialog) {
								ProgressDialogHelper.closeProgressPopup();
							}
						});
						aBookAlertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
							@Override
							public void onDismiss(DialogInterface dialog) {
								ProgressDialogHelper.closeProgressPopup();
							}
						});
						showAlertDialog(aBookAlertDialog);
					}
				});
			}
		});
	}

	// TODO ABVSplashAcitivityとソースが重複するため、一元化する Jang
	private void showCheckAppDialog() throws Exception {
		// アプリのバージョンを確認する
		final ABVEnvironment abvEnvironment = ABVEnvironment.getInstance();
		final ABVDataCache dataCache = ABVDataCache.getInstance();

		boolean isNeedUpdateVersion = false;

		AppLastVersionParameters param;
		SharedPreferences pre = PreferenceUtil.getUserPreference(getActivity());
		// 既にMacAddress使用に同意している場合はMacAddressを使う
		// 認証なしの場合はUUIDを使用する

        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);
        }

        Logger.d(TAG, "[showCheckAppDialog]:1");
		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) {
				isNeedUpdateVersion = true;
			}
		}
		if (isNeedUpdateVersion) {
			// showAlert
			ABookAlertDialog dialog = AlertDialogUtil.createABookAlertDialog(getActivity());
			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) {
					// Download 開始
					DownloadManager downloadManager = (DownloadManager) getActivity().getSystemService(Context.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(getActivity().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));
					if (downloadManager != null) {
						downloadManager.enqueue(request);
					}

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

					// アプリを閉じる
					saveLeaveAppTime();
					getActivity().moveTaskToBack(true);
				}
			});
			dialog.setNegativeButton(R.string.cancel, null);
			showAlertDialog(dialog);
		} else {
			Toast.makeText(getActivity(), getResources().getString(R.string.msg_latest_version), Toast.LENGTH_LONG).show();
		}
	}

	private boolean isNormalSize() {
		return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL;
	}

	private void showAboutABookDialog() {
		Resources r = getResources();
		String version = r.getString(R.string.version_name);
		String releaseDate = r.getString(R.string.release_date);
		String homePage = r.getString(R.string.hope_page);
		final String contactMail = r.getString(R.string.contact_email);
		String copyright = "©" + r.getString(R.string.copy_right);
		//	String message = String.format(r.getString(R.string.about_abook), version, releaseDate, homePage, contactMail, copyright);
		View mainView = View.inflate(getActivity(), R.layout.about_app, null);
		TextView versionText = (TextView) mainView.findViewById(R.id.textVersion);
		versionText.setText(version + "(" + releaseDate + ")\n" + "build:" + RawResourceUtil.getShortGitHash(getActivity()));

		TextView hpText = (TextView) mainView.findViewById(R.id.textHP);
		hpText.setText(homePage);

		TextView contractText = (TextView) mainView.findViewById(R.id.textContact);
		contractText.setText(contactMail);
		contractText.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent mailIntent = new Intent();
				mailIntent.setAction(Intent.ACTION_SEND);
				mailIntent.setType("text/plain");
				mailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { contactMail });
				startActivity(mailIntent);
			}
		});

		TextView copyrightText = (TextView) mainView.findViewById(R.id.textCopyRight);
		copyrightText.setText(copyright);

		//	ABookAlertDialog alertDialog = AlertDialogUtil.scrollableAlertDialog(this, R.string.app_name, message);
		//String title = String.format(r.getString(R.string.about_app), r.getString(R.string.app_name));
		String title = r.getString(R.string.about_app);
		ABookAlertDialog aBookAlertDialog = AlertDialogUtil.createAlertDialog(getActivity(), title);
		aBookAlertDialog.setIcon(R.drawable.icon);// 固定の専用アイコンにする
		aBookAlertDialog.setView(mainView);
		aBookAlertDialog.setPositiveButton(R.string.ok, null);
		showAlertDialog(aBookAlertDialog);
	}

	public void showAlertDialog(AlertDialog alertDialog) {
		showAlertDialog(alertDialog, false);
	}

	protected void showAlertDialog(AlertDialog alertDialog, boolean cancelOutside) {
		if (this.alertDialog != null && this.alertDialog.isShowing()) {
			this.alertDialog.dismiss();
		}
		this.alertDialog = alertDialog;
		alertDialog.show();
		alertDialog.setCanceledOnTouchOutside(cancelOutside);
	}

	protected void saveLeaveAppTime() {
		Logger.d(TAG, "saveLeaveAppTime()");
		PreferenceUtil.putUserPref(getActivity(), UserPrefKey.LEAVE_APP, System.currentTimeMillis());
	}

	// 機器連携のペアリング設定
	private void setPairingSetting() {
		// CHINO機器
		PreferenceGroup chinoDevicePairing = (PreferenceGroup) findPreference(SET_CHINO_PAIRING);

		chinoDevicePairing.setOnPreferenceClickListener(new OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				// アプリ側のBluetooth許可チェック
				ABookPermissionHelper helper = new ABookPermissionHelper(getActivity(), Constant.ABookPermissionType.Bluetooth, null);
				if (!helper.checkMultiPermissions(true)) {
					return true;
				}
				try {
					// ペアリング設定画面（BLE通信）
					Intent intent = new Intent();
					intent.setClass(getActivity(), BlePairingSettingActivity.class);
					startActivity(intent);
				} catch (Exception e) {
					Logger.e(TAG, e);
				}
				return true;
			}
		});

		// SPP通信機器
		PreferenceGroup sppDevicePairing = (PreferenceGroup) findPreference(SET_SPP_PAIRING);

		sppDevicePairing.setOnPreferenceClickListener(new OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				// アプリ側のBluetooth許可チェック
				ABookPermissionHelper helper = new ABookPermissionHelper(getActivity(), Constant.ABookPermissionType.Bluetooth, null);
				if (!helper.checkMultiPermissions(true)) {
					return true;
				}
				try {
					// ペアリング設定画面（SPP通信）
					Intent intent = new Intent();
					intent.setClass(getActivity(), SppBluetoothPairingSettingActivity.class);
					startActivity(intent);
				} catch (Exception e) {
					Logger.e(TAG, e);
				}
				return true;
			}
		});
	}
}
