/*
 * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.micode.notes.ui;

// 导入与账户相关的类，用于账户管理和认证
import android.accounts.Account;
import android.accounts.AccountManager;

// 导入用于操作 Android 应用中的 ActionBar（顶部导航栏）功能
import android.app.ActionBar;

// 导入用于显示和管理弹出对话框的类
import android.app.AlertDialog;

// 导入用于接收广播消息的类
import android.content.BroadcastReceiver;

// 导入用于在 ContentProvider 中存储和插入数据的类
import android.content.ContentValues;

// 导入 Android 应用的上下文类，用于访问全局应用信息和资源
import android.content.Context;

// 导入用于显示和管理对话框按钮点击事件的接口
import android.content.DialogInterface;

// 导入用于启动新活动或广播的 Intent 类
import android.content.Intent;

// 导入用于过滤广播消息的 IntentFilter 类
import android.content.IntentFilter;

// 导入用于访问和操作应用设置的类
import android.content.SharedPreferences;

// 导入用于传递数据和保存状态的类
import android.os.Bundle;

// 导入与偏好设置界面相关的类，用于创建设置项和响应设置点击事件
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;

// 导入用于文本操作的工具类，提供字符串处理方法
import android.text.TextUtils;

// 导入用于日期时间格式化的工具类
import android.text.format.DateFormat;

// 导入用于视图管理和菜单操作的类
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

// 导入常用的 UI 控件类，如按钮、文本视图和弹出提示框
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

// 导入应用的资源文件引用类，包含应用的所有资源（如字符串、布局等）
import net.micode.notes.R;

// 导入与笔记相关的数据模型类，定义了笔记数据结构
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;

// 导入与 Google 任务同步服务相关的类，用于同步任务数据
import net.micode.notes.gtask.remote.GTaskSyncService;


public class NotesPreferenceActivity extends PreferenceActivity {
    // 定义常量，存储偏好设置的名称
    public static final String PREFERENCE_NAME = "notes_preferences";

    // 定义常量，存储同步账户名称的键
    public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name";

    // 定义常量，存储最后同步时间的键
    public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time";

    // 定义常量，存储背景颜色随机显示的设置键
    public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear";

    // 私有常量，存储同步账户的键
    private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key";

    // 私有常量，存储账户信息的过滤键
    private static final String AUTHORITIES_FILTER_KEY = "authorities";

    // 存储账户相关设置的类别
    private PreferenceCategory mAccountCategory;

    // 用于接收同步服务广播的接收器
    private GTaskReceiver mReceiver;

    // 存储原始账户列表
    private Account[] mOriAccounts;

    // 标记是否添加了新账户
    private boolean mHasAddedAccount;

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        // 使用应用图标作为导航栏的“向上”按钮
        getActionBar().setDisplayHomeAsUpEnabled(true);

        // 加载偏好设置界面资源
        addPreferencesFromResource(R.xml.preferences);

        // 获取账户设置类别对象
        mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);

        // 初始化 GTaskReceiver 接收器，用于接收同步相关广播
        mReceiver = new GTaskReceiver();

        // 创建 IntentFilter，注册 GTaskSyncService 广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);
        registerReceiver(mReceiver, filter);

        // 初始化原始账户列表为空
        mOriAccounts = null;

        // 加载设置界面的头部视图
        View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null);
        getListView().addHeaderView(header, null, true);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // 如果添加了新账户，则尝试自动设置同步账户
        if (mHasAddedAccount) {
            // 获取当前所有的 Google 账户
            Account[] accounts = getGoogleAccounts();

            // 如果原始账户列表不为空且当前账户数量大于原始账户数量
            if (mOriAccounts != null && accounts.length > mOriAccounts.length) {
                // 遍历当前账户列表，查找新增的账户
                for (Account accountNew : accounts) {
                    boolean found = false;

                    // 遍历原始账户列表，检查新增账户是否已存在
                    for (Account accountOld : mOriAccounts) {
                        // 如果找到匹配的账户，则标记为已找到
                        if (TextUtils.equals(accountOld.name, accountNew.name)) {
                            found = true;
                            break;
                        }
                    }

                    // 如果新增账户没有在原始账户列表中找到，则设置为同步账户
                    if (!found) {
                        setSyncAccount(accountNew.name);
                        break;
                    }
                }
            }
        }
        refreshUI();
    }

@Override
protected void onDestroy() {
    // 如果 mReceiver 已初始化，则注销广播接收器，防止内存泄漏
    if (mReceiver != null) {
        unregisterReceiver(mReceiver);
    }
    // 调用父类的 onDestroy，确保正确销毁 Activity
    super.onDestroy();
}


   private void loadAccountPreference() {
    // 清空当前账户类别中的所有项
    mAccountCategory.removeAll();

    // 创建一个新的 Preference 用于账户设置
    Preference accountPref = new Preference(this);

    // 获取当前同步账户的名称
    final String defaultAccount = getSyncAccountName(this);

    // 设置账户项的标题和摘要
    accountPref.setTitle(getString(R.string.preferences_account_title));
    accountPref.setSummary(getString(R.string.preferences_account_summary));

    // 设置点击该项时的处理逻辑
    accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
        public boolean onPreferenceClick(Preference preference) {
            // 如果当前没有进行同步操作
            if (!GTaskSyncService.isSyncing()) {
                if (TextUtils.isEmpty(defaultAccount)) {
                    // 如果没有设置账户，则首次设置账户，弹出选择账户对话框
                    showSelectAccountAlertDialog();
                } else {
                    // 如果已有账户，弹出更改账户的风险提示对话框
                    showChangeAccountConfirmAlertDialog();
                }
            } else {
                // 如果正在同步，提示用户无法更改账户
                Toast.makeText(NotesPreferenceActivity.this,
                        R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT)
                        .show();
            }
            return true;
        }
    });

    // 将账户设置项添加到账户类别中
    mAccountCategory.addPreference(accountPref);
}

   private void loadSyncButton() {
    // 获取同步按钮和最后同步时间的文本视图
    Button syncButton = (Button) findViewById(R.id.preference_sync_button);
    TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview);

    // 根据同步状态设置按钮文本和点击事件
    if (GTaskSyncService.isSyncing()) {
        // 如果当前正在同步，按钮文本为“取消同步”，点击时取消同步
        syncButton.setText(getString(R.string.preferences_button_sync_cancel));
        syncButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // 调用同步服务取消同步操作
                GTaskSyncService.cancelSync(NotesPreferenceActivity.this);
            }
        });
    } else {
        // 如果当前没有同步操作，按钮文本为“立即同步”，点击时开始同步
        syncButton.setText(getString(R.string.preferences_button_sync_immediately));
        syncButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // 调用同步服务开始同步操作
                GTaskSyncService.startSync(NotesPreferenceActivity.this);
            }
        });
    }

    // 设置同步按钮的启用状态：只有在账户不为空时，按钮才启用
    syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this)));

    // 根据同步状态设置最后同步时间文本视图
    if (GTaskSyncService.isSyncing()) {
        // 如果正在同步，显示当前同步进度的文本
        lastSyncTimeView.setText(GTaskSyncService.getProgressString());
        lastSyncTimeView.setVisibility(View.VISIBLE);
    } else {
        // 如果没有同步操作，检查最后同步时间
        long lastSyncTime = getLastSyncTime(this);
        if (lastSyncTime != 0) {
            // 如果有最后同步时间，显示格式化的时间
            lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time,
                    DateFormat.format(getString(R.string.preferences_last_sync_time_format),
                            lastSyncTime)));
            lastSyncTimeView.setVisibility(View.VISIBLE);
        } else {
            // 如果没有同步时间，隐藏最后同步时间文本
            lastSyncTimeView.setVisibility(View.GONE);
        }
    }
}


private void refreshUI() {
    loadAccountPreference();
    loadSyncButton();
}


    private void showSelectAccountAlertDialog() {
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);

    // 设置自定义的对话框标题
    View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);
    TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title);
    titleTextView.setText(getString(R.string.preferences_dialog_select_account_title));  // 设置标题文本
    TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle);
    subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips));    // 设置副标题文本

    // 将自定义标题设置到对话框
    dialogBuilder.setCustomTitle(titleView);
    // 设置对话框的“确定”按钮为空操作，实际没有使用
    dialogBuilder.setPositiveButton(null, null);

    // 获取当前设备上的 Google 账户列表
    Account[] accounts = getGoogleAccounts();
    String defAccount = getSyncAccountName(this);  // 获取当前同步的账户名

    mOriAccounts = accounts;
    mHasAddedAccount = false;

    // 如果有账户可选，显示选择项
    if (accounts.length > 0) {
        CharSequence[] items = new CharSequence[accounts.length];
        final CharSequence[] itemMapping = items;  // 用于存储账户的名称
        int checkedItem = -1;
        int index = 0;

        // 填充账户列表，并找到默认的账户索引
        for (Account account : accounts) {
            if (TextUtils.equals(account.name, defAccount)) {
                checkedItem = index;  // 默认选中的账户
            }
            items[index++] = account.name;  // 将账户名称添加到选项列表
        }

        // 设置单选框列表
        dialogBuilder.setSingleChoiceItems(items, checkedItem,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // 选择账户后，设置同步账户，并刷新 UI
                        setSyncAccount(itemMapping[which].toString());
                        dialog.dismiss();
                        refreshUI();  // 刷新界面
                    }
                });
    }

    // 添加“添加账户”按钮
    View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null);
    dialogBuilder.setView(addAccountView);  // 将其添加到对话框中

    // 显示对话框
    final AlertDialog dialog = dialogBuilder.show();

    // 设置“添加账户”点击事件
    addAccountView.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            mHasAddedAccount = true;
            // 打开添加账户设置界面
            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
            intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] { "gmail-ls" });
            startActivityForResult(intent, -1);  // 启动账户添加页面
            dialog.dismiss();  // 关闭当前对话框
        }
    });
}


        View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null);
dialogBuilder.setView(addAccountView);

final AlertDialog dialog = dialogBuilder.show();
addAccountView.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        mHasAddedAccount = true;
        Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
        intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] {
            "gmail-ls"
        });
        startActivityForResult(intent, -1);
        dialog.dismiss();
    }
});


    private void showChangeAccountConfirmAlertDialog() {
    // 创建一个 AlertDialog.Builder 实例，用于构建弹出的确认对话框
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);

    // 创建自定义标题的视图
    View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);

    // 获取自定义标题视图中的标题文本控件，并设置其显示的文本
    TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title);
    titleTextView.setText(getString(R.string.preferences_dialog_change_account_title,
            getSyncAccountName(this)));  // 显示当前同步账户的名称

    // 获取自定义标题视图中的副标题文本控件，并设置其显示的警告信息
    TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle);
    subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg));  // 设置警告信息

    // 将自定义的标题视图设置为对话框的标题
    dialogBuilder.setCustomTitle(titleView);

    // 创建对话框的菜单选项
    CharSequence[] menuItemArray = new CharSequence[] {
            getString(R.string.preferences_menu_change_account),  // 更改账户选项
            getString(R.string.preferences_menu_remove_account),  // 删除账户选项
            getString(R.string.preferences_menu_cancel)           // 取消选项
    };

    // 为菜单选项设置点击事件监听器
    dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            if (which == 0) {  // 如果用户选择了 "更改账户"
                showSelectAccountAlertDialog();  // 显示选择账户的对话框
            } else if (which == 1) {  // 如果用户选择了 "删除账户"
                removeSyncAccount();  // 删除当前同步的账户
                refreshUI();           // 刷新 UI，更新界面
            }
        }
    });

    // 显示对话框
    dialogBuilder.show();
}


  // 获取所有Google账户
private Account[] getGoogleAccounts() {
    // 获取 AccountManager 实例，这个对象用来管理设备上的账户
    AccountManager accountManager = AccountManager.get(this);

    // 返回所有Google账户，"com.google" 表示Google账户类型
    return accountManager.getAccountsByType("com.google");
}

// 设置同步账户
private void setSyncAccount(String account) {
    // 如果新设置的账户与当前同步账户不同
    if (!getSyncAccountName(this).equals(account)) {
        // 获取 SharedPreferences，用于保存同步账户的配置信息
        SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = settings.edit();

        // 如果账户非空，则将其保存为同步账户
        if (account != null) {
            editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account);
        } else {
            // 如果账户为空，则清除同步账户设置
            editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
        }

        // 提交更改
        editor.commit();

        // 清除上次同步时间（将其设置为0）
        setLastSyncTime(this, 0);

        // 清除与Google任务相关的本地信息
        new Thread(new Runnable() {
            public void run() {
                // 创建一个 ContentValues 对象来更新 Google 任务相关的字段
                ContentValues values = new ContentValues();
                values.put(NoteColumns.GTASK_ID, "");  // 清除任务ID
                values.put(NoteColumns.SYNC_ID, 0);    // 清除同步ID

                // 更新 Notes 内容提供者中的数据，清除与同步相关的信息
                getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null);
            }
        }).start();

        // 弹出提示，告知用户账户设置成功
        Toast.makeText(NotesPreferenceActivity.this,
                getString(R.string.preferences_toast_success_set_accout, account),
                Toast.LENGTH_SHORT).show();
    }
}

// 删除同步账户
private void removeSyncAccount() {
    // 获取 SharedPreferences，删除同步账户设置
    SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = settings.edit();

    // 如果存在同步账户的设置，则移除
    if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) {
        editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME);
    }

    // 如果存在上次同步时间的设置，则移除
    if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) {
        editor.remove(PREFERENCE_LAST_SYNC_TIME);
    }

    // 提交更改
    editor.commit();

    // 清除与Google任务相关的本地信息
    new Thread(new Runnable() {
        public void run() {
            // 创建一个 ContentValues 对象来更新 Google 任务相关的字段
            ContentValues values = new ContentValues();
            values.put(NoteColumns.GTASK_ID, "");  // 清除任务ID
            values.put(NoteColumns.SYNC_ID, 0);    // 清除同步ID

            // 更新 Notes 内容提供者中的数据，清除与同步相关的信息
            getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null);
        }
    }).start();
}


   // 获取同步账户名称
public static String getSyncAccountName(Context context) {
    // 获取 SharedPreferences 实例，存储同步账户名称
    SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
    // 返回同步账户名称，如果没有保存该名称，返回空字符串
    return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}

// 设置上次同步时间
public static void setLastSyncTime(Context context, long time) {
    // 获取 SharedPreferences 实例，存储同步信息
    SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
    // 获取 SharedPreferences 的编辑器，用于修改存储的数据
    SharedPreferences.Editor editor = settings.edit();
    // 将时间值存储到 PREFERENCE_LAST_SYNC_TIME 键中
    editor.putLong(PREFERENCE_LAST_SYNC_TIME, time);
    // 提交更改
    editor.commit();
}

// 获取上次同步时间
public static long getLastSyncTime(Context context) {
    // 获取 SharedPreferences 实例，读取同步信息
    SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
    // 获取上次同步时间，如果没有保存则返回 0（表示没有同步）
    return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0);
}

// 广播接收器，用于接收来自 GTaskSyncService 的广播消息
private class GTaskReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 刷新UI显示
        refreshUI();

        // 检查是否正在同步
        if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) {
            // 获取同步状态显示的 TextView
            TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview);
            // 更新同步状态信息（进度消息）
            syncStatus.setText(intent.getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG));
        }
    }
}

// 处理菜单项点击事件
public boolean onOptionsItemSelected(MenuItem item) {
    // 根据点击的菜单项进行相应的处理
    switch (item.getItemId()) {
        // 点击返回按钮，返回到 NotesListActivity
        case android.R.id.home:
            // 创建返回 Intent，设置标志位清除栈顶活动
            Intent intent = new Intent(this, NotesListActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            // 启动 NotesListActivity
            startActivity(intent);
            return true;
        default:
            // 如果没有匹配的菜单项，返回 false
            return false;
    }
  }
}