/*
 * Copyright (c) 2015. Ncomz. All Rights Reserved
 */

package com.ntels.onecable.view.things;

import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.ntels.onecable.R;
import com.ntels.onecable.common.Constants;
import com.ntels.onecable.common.netatmo.NetatmoHttpClientImpl;
import com.ntels.onecable.common.util.LogUtil;
import com.ntels.onecable.common.util.Util;
import com.ntels.onecable.common.widget.CustomActivity;
import com.ntels.onecable.view.dialog.CustomDialog;

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

import android.app.Activity;
import android.content.Intent;
import android.net.UrlQuerySanitizer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import java.io.UnsupportedEncodingException;

import static com.ntels.onecable.common.http.Response.BAD_REQUEST;

/**
 * <pre>
 * 1. ClassName :   ThingsDeviceNetatmoLogin
 * 2. FileName  :   ThingsDeviceNetatmoLogin.java
 * 3. Package   :   com.ntels.onecable.view.things
 * 4. Date      :   2016-11-25
 * 5. Author    :   aaron
 * 6. Comment   :   Initialize
 * </pre>
 */
public class ThingsDeviceNetatmoLogin extends CustomActivity implements
        CustomDialog.OnMsgAlterToResult {

    private static final String TAG = ThingsDeviceNetatmoLogin.class.getSimpleName();

    private static final int PROGRESS_LOADING_COMPLETE = 100;

    /*통신 관련*/
    private static final int MSG_COM_P_NETATMO_LOGIN = 1;
    private int mType;

    private static final String APP_SCHEME = "kneet-app:";

    /*공통*/
    private Activity mActivity;
    private Intent mIntent;
    private Util mUtil = new Util();
    private CustomDialog mCustomDialog = new CustomDialog();
    private WebView mNetatmoWebView = null;
    private ProgressBar mNetatmoProgressBar = null;
    private String mAuthToken = "";

    @Override
    public void onCreate(Bundle savedInstanceState) {

        getWindow().requestFeature(Window.FEATURE_PROGRESS);

        super.onCreate(savedInstanceState);

        mActivity = ThingsDeviceNetatmoLogin.this;
        mCustomDialog.setOnMsgAlterToResultEvent(this);

        View viewToLoad = LayoutInflater.from(mActivity)
                .inflate(R.layout.things_device_netatmo_auth, null);
        this.setContentView(viewToLoad);

        displayView();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case Constants.ACT_THINGS_DEVICE_NETATMO_CAMERA_LIST:
                    setResult(RESULT_OK, data);
                    finish();
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void resultCustomDialogResponse(int msgId, int btnResult) {

        switch (msgId) {

            case Constants.MSG000:
                onBackPressed();
                break;

            default:
                break;
        }
    }

    /**
     * UI display.
     */
    private void displayView() {
        mNetatmoProgressBar = (ProgressBar) findViewById(R.id.netatmoProgressBar);

        netatmoWebViewSetting();
        LogUtil.i(TAG, "loadUrl - " + getString(R.string.netatmo_auth));
        mNetatmoWebView.loadUrl(getString(R.string.netatmo_auth, getString(R.string.client_id)));
    }

    /**
     * 넷타모에 로그인하여 사용자 token정보를 받아온다.
     */
    private void netatmoLogin() {
        final NetatmoHttpClientImpl netatmoHttpClientImpl = new NetatmoHttpClientImpl(this);
        netatmoHttpClientImpl.login(mAuthToken,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        JSONObject jsonObject;
                        try {
                            jsonObject = new JSONObject(response);
                            netatmoHttpClientImpl.processOAuthResponse(jsonObject);
                            mIntent = new Intent(mActivity, ThingsDeviceNetatmoCameraList.class);
                            mUtil.callActivityForResultNoAnim(mActivity, mIntent,
                                    Constants.ACT_THINGS_DEVICE_NETATMO_CAMERA_LIST);
                        } catch (JSONException ex) {
                            ex.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        LogUtil.e(TAG, error.toString());
                        String errorMessage = null;

                        NetworkResponse response = error.networkResponse;
                        if (response != null && response.data != null) {
                            try {
                                errorMessage = new JSONObject(
                                        new String(response.data, "UTF-8")).getString("error");
                            } catch (UnsupportedEncodingException ex) {
                                ex.printStackTrace();
                            } catch (JSONException ex) {
                                ex.printStackTrace();
                            }
                            LogUtil.e(TAG, errorMessage);

                            switch (response.statusCode) {
                                case BAD_REQUEST:
                                    if ("invalid_grant".equals(errorMessage)) {
                                        mCustomDialog.msgAlert(mActivity, Constants.MSG915);
                                    } else if ("too_many_connections".equals(errorMessage)) {
                                        mCustomDialog.msgAlert(mActivity, Constants.MSG914);
                                    } else {
                                        mCustomDialog.msgAlert(mActivity, Constants.MSG000,
                                                errorMessage);
                                    }
                                    break;

                                default:
                                    mCustomDialog.msgAlert(mActivity, Constants.MSG000,
                                            errorMessage);
                                    break;
                            }
                        }
                    }
                }
        );

    }

    Handler comHandler = new Handler(new IncomingHandlerCallBack());

    /**
     * 서버 요청 핸들러.
     */
    class IncomingHandlerCallBack implements Handler.Callback {

        @Override
        public boolean handleMessage(Message msg) {

            mType = msg.what;
            switch (msg.what) {
                case MSG_COM_P_NETATMO_LOGIN:
                    netatmoLogin();
                    break;

                default:
                    break;
            }
            return true;
        }
    }

    private void clearCache() {
        mNetatmoWebView.clearHistory();
        mNetatmoWebView.clearCache(true);
        mNetatmoWebView.clearView();
        CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(this);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        cookieManager.removeSessionCookie();
        cookieSyncManager.sync();
    }

    private void netatmoWebViewSetting() {
        mNetatmoWebView = (WebView) findViewById(R.id.netatmoWebView);
        clearCache();
        mNetatmoWebView.getSettings().setJavaScriptEnabled(true);
        mNetatmoWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mNetatmoWebView.getSettings().setAppCacheEnabled(false);
        mNetatmoWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mNetatmoWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        mNetatmoWebView.getSettings().setLoadWithOverviewMode(true);
        mNetatmoWebView.getSettings().setUseWideViewPort(true);
        mNetatmoWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        mNetatmoWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == PROGRESS_LOADING_COMPLETE) {
                    mNetatmoProgressBar.setVisibility(View.GONE);
                    return;
                }
                mNetatmoProgressBar.setVisibility(View.VISIBLE);
                mNetatmoProgressBar.setProgress(newProgress);
            }
        });
        mNetatmoWebView.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                LogUtil.i(TAG, "shouldOverrideUrlLoading::url - " + url);
                if (url.startsWith(APP_SCHEME)) {
                    LogUtil.i(TAG, "url - " + url);
                    UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(url);
                    if (null != sanitizer.getValue("code")) {
                        mAuthToken = sanitizer.getValue("code");
                        LogUtil.i(TAG, "mAuthToken - " + mAuthToken);
                        comHandler.sendEmptyMessageDelayed(MSG_COM_P_NETATMO_LOGIN,
                                Constants.HANDLER_DELAY_MILLIS);
                    } else {
                        if (null != sanitizer.getValue("error")) {
                            String errorCode = sanitizer.getValue("error");
                            if ("access_denied".equals(errorCode)) {
                                mCustomDialog.msgAlert(mActivity, Constants.MSG918);
                            } else {
                                mCustomDialog.msgAlert(mActivity, Constants.MSG000,
                                        sanitizer.getValue("error"));
                            }
                            return true;
                        }
                        onBackPressed();
                    }
                    return true;
                }
                return false;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                view.invalidate();
            }
        });
    }

}
