package cn.m4399.operate.samples;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import cn.m4399.operate.OperateCenter;
import cn.m4399.operate.UpgradeInfo;
import cn.m4399.operate.UpgradeProgress;

/*
 * 自定义更新
 */
class UpgradeController {
    public static final float M = 1024 * 1024;
    private static final String TAG = "Upgrade";
    private Activity mainActivity;

    void doUpgrade(final Activity activity, View view) {
        view.setClickable(false);
        mainActivity = activity;
        final ProgressDialog progress = newProgressDialog();
        OperateCenter.getInstance().doCheck(activity, new UpgradeProgress<UpgradeInfo>() {
            @Override
            public void onStart() {
                progress.setMessage(getString(R.string.upgrade_check_version_progress));
                progress.show();
            }

            @Override
            public void onFinished(int code, String message, UpgradeInfo info) {
                showUpdateInfo(info);
                progress.dismiss();
            }
        });
        view.setClickable(true);
    }

    // 根据 info 对象内容展示更新对话框
    // 需要区分几种情况：
    // 1 检查更新成功
    //     1.1 有新版本
    //         1.1.1 本地有下载好的文件，展示安装对话框，后续调用doInstall接口
    //         1.1.2 本地没有下载好的文件，展示下载对话框，后续调用doInstall接口
    //     1.2 无新版本，游戏方更加需要决定是否需要提升
    // 2 检查更新失败，游戏方根据需要提供重试按钮，后续调用doCheck接口
    private void showUpdateInfo(final UpgradeInfo info) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
        StringBuilder msgBuilder = new StringBuilder();

        int code = info.code();

        if (code == UpgradeInfo.STATUS_UP_TO_DATE) {
            msgBuilder.append(getString(R.string.upgrade_new_release_not_found));
            builder.setNegativeButton(getString(R.string.upgrade_new_release_confirm), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
        } else if (code == UpgradeInfo.STATUS_NEED_UPGRADE) {
            msgBuilder.append(getString(R.string.upgrade_new_release_version, info.apkVersionName(), info.apkVersionCode()))
                    .append(getString(R.string.upgrade_new_release_time))
                    .append(new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date(info.dateline())))
                    .append(getString(R.string.upgrade_new_release_size, info.apkSizeByte() / M, info.upgradeSize() / M))
                    .append(Html.fromHtml(info.upgradeMsg()));

            final boolean havePreparedFile = info.havePreparedFile();
            String action = havePreparedFile ? getString(R.string.upgrade_install_action_at_once) : getString(R.string.upgrade_download_action_start);

            builder.setPositiveButton(action, new DialogInterface.OnClickListener() {
                boolean clicked;

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (!clicked) {
                        if (havePreparedFile)
                            OperateCenter.getInstance().doInstall(info, new UpgradeProgress<Void>() {
                                @Override
                                public void onFinished(int code, String message, Void aVoid) {
                                    if (code != UpgradeProgress.SUCCESS) {
                                        Log.e(TAG, "Install failed: " + message);
                                    }
                                }
                            });
                        else
                            doDownload(info);
                        clicked = true;
                    } else
                        toastMessage(R.string.upgrade_warning_repeat_action);
                }
            });

            if (!info.isCompel())
                builder.setNegativeButton(getString(R.string.upgrade_download_action_cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        } else {
            msgBuilder.append(info.message());
            builder.setNegativeButton(getString(R.string.upgrade_new_release_confirm), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
        }

        Dialog dialog = builder.setCancelable(!info.isCompel())
                .setTitle(R.string.upgrade_check_version_action)
                .setMessage(msgBuilder)
                .create();
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    private void doDownload(final UpgradeInfo info) {
        final ProgressDialog progress = newProgressDialog();
        progress.setMessage(getString(R.string.upgrade_download_action_prepare));
        progress.show();

        OperateCenter.getInstance().doDownload(info, new UpgradeProgress<Void>() {
            @Override
            public void onStart() {
                progress.setMessage(getString(R.string.upgrade_download_action_start));
            }

            @Override
            public void onProgress(long... ps) {
                long written = ps[0];
                long total = ps[1];
                progress.setMessage(getString(R.string.upgrade_download_progress, written * 100 / total));
            }

            @Override
            public void onFinished(int code, String message, Void aVoid) {
                if (code == SUCCESS || code == SUCCESS_ALREADY)
                    doInstall(info);
                else
                    toastMessage(R.string.upgrade_download_action_failed);
                progress.dismiss();
            }
        });
    }

    private void doInstall(final UpgradeInfo info) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity)
                .setCancelable(false)
                .setTitle(R.string.upgrade_install_action_at_once)
                .setMessage(R.string.upgrade_install_message_confirm)
                .setPositiveButton(R.string.upgrade_install_action, null);

        if (!info.isCompel())
            builder.setNegativeButton(getString(R.string.upgrade_install_action_refused_now), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });

        final AlertDialog dialog = builder.create();
        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialogInterface) {
                final Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        button.setEnabled(false); // 防止误点击
                        dialog.setMessage(UpgradeController.this.getString(R.string.upgrade_install_prepare_progress));

                        OperateCenter.getInstance().doInstall(info, new UpgradeProgress<Void>() {
                            @Override
                            public void onStart() {
                            }

                            @Override
                            public void onProgress(long... ps) {
                                if (ps[0] == UpgradeProgress.PROGRESS_INSTALLING) {
                                    dialog.setMessage(getString(R.string.upgrade_install_prepare_success));
                                    button.setEnabled(true);
                                }
                            }

                            @Override
                            public void onFinished(int code, String message, Void aVoid) {
                                dialog.setMessage(message);
                            }
                        });
                    }
                });
            }
        });
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    private ProgressDialog newProgressDialog() {
        ProgressDialog progress = new ProgressDialog(mainActivity);
        progress.setCancelable(false);
        progress.setCanceledOnTouchOutside(false);
        progress.setTitle(R.string.upgrade_check_version_action);
        progress.setIndeterminate(false);
        return progress;
    }

    private void toastMessage(int msgId) {
        Toast.makeText(mainActivity, msgId, Toast.LENGTH_SHORT).show();
    }

    private String getString(int id, Object... formatter) {
        return mainActivity.getString(id, formatter);
    }
}
