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

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import jp.agentec.abook.abv.bl.acms.client.json.content.ContentJSON;
import jp.agentec.abook.abv.bl.acms.type.AcmsApis;
import jp.agentec.abook.abv.bl.acms.type.OperationType;
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.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.data.dao.OperationDao;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.dto.OperationDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ContentObjectLogLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.cl.util.ContentLogUtil;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVCheckContentViewActivity;
import jp.agentec.abook.abv.ui.common.activity.ABVContentViewActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
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.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.home.helper.ContentViewHelper;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.FileUtil;

public class ParentWebViewActivity extends ABVCheckContentViewActivity {
    private static final String TAG = "ParentWebViewActivity";

    private LinearLayout historyLayout;
    private ImageButton addSceneButton;

    protected ImageButton promoteBtn;
    protected ImageButton pauseBtn;
    protected ImageButton mBtnRemoteStart;
    protected Button historyListBtn;
    protected ImageButton btnWebClose;
    protected Button closeButton;
    protected Button btnLinkOriginalBack;
    protected Button btnWebBack;
    protected Button btnWebForward;
    private ProgressBar m_progress;
    protected ContentDto mContentDto;

    protected void commonOnCreate() {
        mContentDto = AbstractDao.getDao(ContentDao.class).getContent(contentId);
        historyLayout = (LinearLayout) findViewById(R.id.historyLayout);
        addSceneButton = (ImageButton) findViewById(R.id.btn_add_scene);
        taskListButton = (ImageButton) findViewById(R.id.btn_show_task_list);
        helpButton = (ImageButton) findViewById(R.id.btn_help);
        btnWebClose = (ImageButton) findViewById(R.id.btnWebClose);
        closeButton = (Button) findViewById(R.id.closeBtn);
        historyListBtn = (Button) findViewById(R.id.btn_history_list);
        subMenuBtn = (ImageButton) findViewById(R.id.btn_sub_menu);
        exitMeetingBtn = (ImageButton) findViewById(R.id.btn_exitMeeting);
        mBtnRemoteStart = (ImageButton) findViewById(R.id.btn_remote_start);
        pauseBtn = (ImageButton) findViewById(R.id.btn_remote_pause);
        promoteBtn = (ImageButton) findViewById(R.id.btn_promote);
        btnWebBack = (Button) findViewById(R.id.btnWebBack);
        btnWebForward = (Button) findViewById(R.id.btnWebForward);
        m_progress = (ProgressBar) findViewById(R.id.refresh_prog);
        printButton = (ImageButton) findViewById(R.id.btn_print);
        // 簡易帳票印刷ボタン
        printButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Logger.d(TAG, "Print");
                showPrintTargetSelect();
            }
        });
        btnLinkOriginalBack = (Button) findViewById(R.id.btn_link_original_back);

        if (!isLinkedContent) {
            addSceneButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startCameraIntent(ABOOK_CHECK_SELECT_SCENE, "Camera", ABookKeys.IMAGE, false);
                }
            });
            createCheckToolbar();
        }
    }

    protected void commonOnReceivedResponseHeaders(String uri, int statusCode) {
        if (uri.contains("vtour") || uri.contains("authByCheck")) {
            if(statusCode >= 400) {
                // エラーのため、空のURLをロードさせ、白い画面で表示させる
                webViewLoadUrl("");
                ABookAlertDialog alertDialog = AlertDialogUtil.createAlertDialog(this, R.string.app_name);
                // リソースパターンの適用
                alertDialog.setMessage(String.format(PatternStringUtil.patternToString(getApplicationContext(),
                                                        R.string.error_msg_open_pano_edit,
                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)),
                                                        statusCode + ""));
                // リソースパターンの適用
                alertDialog.setPositiveButton(PatternStringUtil.patternToInt(getApplicationContext(),
                                                R.string.ok,
                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                finish();
                            }
                        });
                alertDialog.show();
            }
        }
    }

    protected void commonProgressChanged(int progress) {
        setVisbilityProgress(true);
        if (progress >= 100) {
            setVisbilityProgress(false);
        }
    }
    private OperationDao mOperationDao = AbstractDao.getDao(OperationDao.class);
    /**
     * 簡易帳票印刷ボタン活性制御
     * 簡易帳票区分が1のデータが存在する場合表示、それ以外非表示
     */
    private void printButtonActivityControl() {
        OperationDto operation = mOperationDao.getOperation(mOperationId);
        if (operation != null && operation.quickReport == 1 && ABVDataCache.getInstance().serviceOption.isUnableIOReport()) {
            printButton.setVisibility(View.VISIBLE);
        } else {
            printButton.setVisibility(View.GONE);
        }
    }

    @Override
    protected  void commonConfigureHeader() {
        if (mStatusCode == Constant.XWalkWebViewDisplayStatus.InitView) {
            helpButton.setVisibility(View.VISIBLE);
            printButtonActivityControl();

        } else {
            // ヘルプボタンを表示しない時、IO帳票ボタンも表示しない。
            helpButton.setVisibility(View.INVISIBLE);
            printButton.setVisibility(View.INVISIBLE);
        }

        if (Constant.XWalkWebViewDisplayStatus.TaskView == mStatusCode) {
            operationHomeButton.setVisibility(View.GONE);
            taskListButton.setVisibility(View.GONE);
        } else {
            operationHomeButton.setVisibility(View.VISIBLE);
            if (mOperationType != OperationType.LIST) {
                taskListButton.setVisibility(View.VISIBLE);
            }
            progressDialog.setProgress(0);
            //中心温度計接続を切る
            bleManagerDisconnect();
        }
    }

    @Override
    protected void commonConfigureRemote() {

        historyLayout = (LinearLayout) findViewById(R.id.historyLayout);
        if (ContentJSON.KEY_PANO_IMAGE_TYPE.equals(mContentDto.contentType) || ContentJSON.KEY_PANO_MOVIE_TYPE.equals(mContentDto.contentType)) {
            historyLayout.setVisibility(View.GONE);
        }
        addSceneButton = (ImageButton) findViewById(R.id.btn_add_scene);
        taskListButton = (ImageButton) findViewById(R.id.btn_show_task_list);
        helpButton = (ImageButton) findViewById(R.id.btn_help);
        operationHomeButton = (Button) findViewById(R.id.btn_operation_home);

        if (mXWalkOpenType == Constant.XWalkOpenType.DEFAULT) {
            helpButton.setVisibility(View.GONE);
            printButton.setVisibility(View.GONE);
            operationHomeButton.setVisibility(View.GONE);
            addSceneButton.setVisibility(View.GONE);
            taskListButton.setVisibility(View.GONE);
        } else {
            if (mOperationType == OperationType.LIST && operationDto.reportType != Constant.ReportType.RoutineTask && operationDto.enableAddReport == Constant.EnableAddReport.NO) {
                // リストタイプ且つ報告タイプが定期点検以外で作業追加区分が無しの場合、ヘルプボタンを非表示
                helpButton.setVisibility(View.INVISIBLE);
            } else {
                helpButton.setVisibility(View.VISIBLE);
                printButtonActivityControl();
            }
            operationHomeButton.setVisibility(View.VISIBLE);

            btnWebBack.setVisibility(View.GONE);
            btnWebForward.setVisibility(View.GONE);
            subMenuBtn.setVisibility(View.GONE);
            closeButton.setVisibility(View.GONE);
            btnLinkOriginalBack.setVisibility(View.GONE);
            historyListBtn.setVisibility(View.GONE);
            btnWebClose.setVisibility(View.GONE);
            pauseBtn.setVisibility(View.GONE);
            exitMeetingBtn.setVisibility(View.GONE);
            mBtnRemoteStart.setVisibility(View.GONE);
            pauseBtn.setVisibility(View.GONE);
            promoteBtn.setVisibility(View.GONE);
        }

        switch (mXWalkOpenType) {
            case Constant.XWalkOpenType.TASK_REPORT:
                if (mOperationType == OperationType.LIST) {
                    taskListButton.setVisibility(View.GONE);
                } else {
                    taskListButton.setVisibility(View.VISIBLE);
                }
                operationNameTitle.setVisibility(View.VISIBLE);
                break;
            case Constant.XWalkOpenType.PANO_EDIT:
                addSceneButton.setVisibility(View.VISIBLE);
                taskListButton.setVisibility(View.GONE);
                operationNameTitle.setVisibility(View.VISIBLE);
                break;
        }
    }

    protected void setVisbilityProgress(boolean visible) {
        if (visible) {
            m_progress.setVisibility(View.VISIBLE);
        } else {
            m_progress.setVisibility(View.GONE);
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (isLinkedContent) {
                goToBack();
            } else {
                if (mOperationId <= 0) { //コンテンツ間リンク及び通常リンクコンテンツのみ戻る機能有効
                    finishActivity();
                }
            }
        } else {
            return super.onKeyUp(keyCode, event);
        }
        return false;
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        Logger.d(TAG, "onDestroy");
        if (mXWalkOpenType == Constant.XWalkOpenType.TASK_REPORT) {
            // tempファイル削除
            FileUtil.delete(ABVEnvironment.getInstance().getTempDirPath(contentId));
            FileUtil.delete(ABVEnvironment.getInstance().getAttachedMoviesFilePath(contentId));
        }
        super.onDestroy();
    }

    // シーン追加ダイアログ表示
    protected void confirmEntrySceneDialog(Uri result) {
        // 画像
        try {
            final Uri responseUri = attachmentImageProcessing(result);
            // リソースパターンの適用
            ABookAlertDialog alertDialog = AlertDialogUtil.createAlertDialog(this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                            R.string.pano_edit,
                                                                                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
            alertDialog.setMessage(PatternStringUtil.patternToInt(getApplicationContext(),
                                    R.string.msg_confirm_entry_scene,
                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
            alertDialog.setNegativeButton(R.string.cancel, null);
            alertDialog.setPositiveButton(R.string.ok,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            // リソースパターンの適用
                            showProgressView(PatternStringUtil.patternToString(getApplicationContext(),
                                                R.string.msg_common_processing,
                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                            CommonExecutor.execute(new Runnable() {
                                @Override
                                public void run() {
                                    if (responseUri != null && responseUri.getPath() != null) {
                                        File file = new File(responseUri.getPath());
                                        try {
                                            final Integer resourceId = AbstractLogic.getLogic(OperationLogic.class).sendScene(file);
                                            if (resourceId != null) {
                                                runOnUiThread(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        progressDialogHorizontal.setProgress(20);
                                                        webViewLoadUrl(String.format("javascript:CHK_E.checkResourceEntry('%s')", resourceId));
                                                    }
                                                });

                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        int progress = progressDialogHorizontal.getProgress();

                                                        if (progress == 0) {
                                                            return;
                                                        } else if (progress == 100) {
                                                            progressDialogHorizontal.setProgress(0);
                                                            closeProgressPopup();
                                                        } else if (progress < 100 && progress > 80) {
                                                            progressDialogHorizontal.setProgress(progress + 1);
                                                            handler.postDelayed(this, 2000);
                                                        } else if (progress <= 80 && progress >= 60) {
                                                            progressDialogHorizontal.setProgress(progress + 2);
                                                            handler.postDelayed(this, 1000);
                                                        }  else if (progress < 60) {
                                                            progressDialogHorizontal.setProgress(progress + 4);
                                                            handler.postDelayed(this, 1000);
                                                        }
                                                    }
                                                });
                                            } else {
                                                Logger.e(TAG, "resourceId == null");
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        closeProgressPopup();
                                                    }
                                                });
                                            }
                                        } catch (Exception e) {
                                            Logger.e(TAG, e);
                                            handler.post(new Runnable() {
                                                @Override
                                                public void run() {
                                                    closeProgressPopup();
                                                    showFailedSceneApiDialog();
                                                }
                                            });
                                        } finally {
                                            //アプリ内のファイルのみ削除（Galleryファイルは削除しない）
                                            if (mLocalFile != null && mLocalFile.getPath().contains(getPackageName())) {
                                                FileUtil.delete(mLocalFile);
                                            }
                                            mLocalFile = null;
                                        }

                                    }
                                }
                            });
                        }
                    });
            alertDialog.show();
        } catch (Exception e) {
            Logger.e(TAG, e);
            closeProgressPopup();
            ErrorMessage.showErrorMessageToast(getApplicationContext(), ErrorCode.E107);
        }
    }

    /**
     * シーン追加API通信で失敗時のダイアログ表示
     */
    private void showFailedSceneApiDialog() {
        // リソースパターンの適用
        ABookAlertDialog alertDialog = AlertDialogUtil.createAlertDialog(getApplicationContext(), PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                        R.string.pano_edit,
                                                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        alertDialog.setMessage(PatternStringUtil.patternToInt(getApplicationContext(),
                                R.string.msg_sence_regist_api_failed,
                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        alertDialog.setPositiveButton(PatternStringUtil.patternToInt(getApplicationContext(),
                                        R.string.ok,
                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)),
                                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        alertDialog.show();
    }

    public long getOperationId() {
        return mOperationId;
    }



    public String doParameter(Map<String, String> param, Context context, long contentId, Integer lastPageNo, Integer readingLogId, Date lastPageStartDate, Callback callback) {
        String uri = param.get(ABookKeys.URI);
        Long dstContentId = Long.valueOf(param.get("contentId"));
        Integer pageNo = param.containsKey("pageNo")? Integer.valueOf(param.get("pageNo")) - 1: 0; // 1スタートを0スタート

        if (uri.startsWith(ABookKeys.CONTENTLINK)) {
            int result = ContentViewHelper.getInstance().linkDownloadChecked(dstContentId, pageNo);
            Logger.d(TAG, "linkDownloadChecked result=%s", result);
            if (result == ContentViewHelper.LinkContentStatus.NoExist) {
                return context.getString(R.string.msg_require_content_refresh);
            }
            ContentLogUtil.getInstance().endContentPageReadLog(contentId, lastPageNo, readingLogId);
            if (result == ContentViewHelper.LinkContentStatus.DownloadedContent) {
                Activity currentActivity = ActivityHandlingHelper.getInstance().getContentViewActivity();
                // HTMLWebViewActivityの場合はfinish()を実施して、コンテンツを開く
                if (currentActivity instanceof HTMLWebViewActivity) {
                    currentActivity.finish();
                }
                ActivityHandlingHelper.getInstance().startContentActivity(dstContentId, pageNo);
            } else {
                int prePage = 0;
                ABVContentViewActivity viewActivity = ActivityHandlingHelper.getInstance().getContentViewActivity();
                if (viewActivity != null) {
                    prePage = viewActivity.getCurrentPageNumber();
                }
                if (ActivityHandlingHelper.getInstance().checkContent(dstContentId, prePage)) {
                    ActivityHandlingHelper.getInstance().startContentActivity(dstContentId, prePage);
                }
                return null;
            }
        } else if (uri.startsWith(ABookKeys.DETAILLOG)) {
            if (readingLogId == null) { // 開始
                readingLogId = ContentLogUtil.getInstance().startContentReadLog(context, contentId, PreferenceUtil.getUserPref(context, AppDefType.DefPrefKey.PERMISSION_ACCESS_LOCATION, false));
            }
            AbstractLogic.getLogic(ContentObjectLogLogic.class).insertContentObjectLog(contentId, readingLogId, pageNo, param);
        } else if (uri.startsWith(ABookKeys.MOVEPAGE)) { // ブラウザから送られてきた時間は使わず、アプリの時間を用いる
            if (readingLogId == null) { // 開始ページ
                readingLogId = ContentLogUtil.getInstance().startContentReadLog(context, contentId, PreferenceUtil.getUserPref(context, AppDefType.DefPrefKey.PERMISSION_ACCESS_LOCATION, false));
                ContentLogUtil.getInstance().startContentPageReadLog(contentId, readingLogId, pageNo);
            } else {
                if (param.get("readingEndDate") != null) { // 終了時刻有
                    ContentLogUtil.getInstance().endContentPageReadLog(contentId, pageNo, readingLogId);
                } else {
                    ContentLogUtil.getInstance().endContentPageReadLog(contentId, lastPageNo, readingLogId); // crosswalkのときもjsではローカルサーバに送るが受取がないためここで終了を呼び出す。ただしローカルサーバを使う場合2重に処理が走る。
                    ContentLogUtil.getInstance().startContentPageReadLog(contentId, readingLogId, pageNo);
                }
            }
            String[] readingStartDate = param.get("readingStartDate").split(",");
            Date pageStartDate = DateTimeUtil.toDate(readingStartDate[0], readingStartDate[1], DateTimeFormat.yyyyMMddHHmmss_hyphen);
            if (lastPageStartDate == null || lastPageStartDate.before(pageStartDate)) {
                lastPageStartDate = pageStartDate;
                lastPageNo = pageNo;
            }
        }

        Map<String, Object> ret = new HashMap<String, Object>();
        if (lastPageStartDate != null) {
            ret.put("lastPageStartDate", lastPageStartDate);
        }
        if (lastPageNo != null) {
            ret.put("lastPageNo", lastPageNo);
        }
        if (readingLogId != null) {
            ret.put("readingLogId", readingLogId);
        }
        callback.callback(ret);

        return null;
    }

    // 上位のClassからHTML側のコールを行うための処理
    public void callViewLoadUrl(String url) {
        webViewLoadUrl(url);
    }

    // キーボードのエンターを検知してJavascriptを実行
    protected void doEnterEvent() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Logger.i(TAG, "javascript:CHK.notifyMoveForcus()");
                webViewLoadUrl("javascript:CHK.notifyMoveForcus()");
            }
        });
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        // Enterキー入力イベントのみ検知、他の検知はonKeyUpで行う
        if (event.getAction()==KeyEvent.ACTION_DOWN || event.getAction()==KeyEvent.ACTION_UP) {
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_ENTER:
                    // バーコード読み取り時のEnterキー入力イベントをハンドリング
                    doEnterEvent();
                    break;
            }
        }
        return super.dispatchKeyEvent(event);
    }
    /**
     * 簡易帳票印刷対象選択画面表示
     */
    private void showPrintTargetSelect() {
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            showDisConnectNetworkDialog();
            return;
        }
        Intent intent = new Intent();
        intent.setClass(ParentWebViewActivity.this, OnlineHTMLWebViewActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("LINKURL", AcmsApis.getApiUrl(ABVEnvironment.getInstance().acmsAddress, ABVDataCache.getInstance().getUrlPath(), AcmsApis.ApiQuickReportRevision));
        intent.putExtra("operationId", mOperationId);
        startActivity(intent, NaviConsts.Right);
    }
    /**
     * インターネットが繋がってない場合のダイアログ表示
     */
    private void showDisConnectNetworkDialog() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                final ABookAlertDialog messageDialog = AlertDialogUtil.createAlertDialog(ParentWebViewActivity.this, R.string.app_name);
                messageDialog.setMessage(getString(R.string.msg_network_offline));
                messageDialog.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int whichButton) {
                        messageDialog.dismiss();
                    }
                });
                messageDialog.show();
            }
        });
    }
}
