/*
 * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 您可以在遵守 License 的前提下使用本文件。
 * 您可以从以下地址获取 License 副本：
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * 除非适用法律要求或书面同意，本软件根据 License 分发时“按现状”提供，
 * 不附带任何明示或暗示的保证或条件。请参阅 License 了解具体的权限和限制。
 */

package net.micode.notes.gtask.remote;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;

import net.micode.notes.R;
import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;

/**
 * 处理Google Tasks同步的异步任务类
 * 负责在后台执行同步操作，并通过通知和回调机制反馈状态
 */
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {

    // 同步通知的唯一标识ID
    private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;

    // 完成回调接口，用于通知同步结束
    public interface OnCompleteListener {
        void onComplete(); // 同步完成时的回调方法
    }

    private Context mContext; // 应用上下文
    private NotificationManager mNotifiManager; // 通知管理器
    private GTaskManager mTaskManager; // 任务管理实例
    private OnCompleteListener mOnCompleteListener; // 完成回调监听器

    /**
     * 构造函数
     * @param context 应用上下文
     * @param listener 同步完成回调监听器
     */
    public GTaskASyncTask(Context context, OnCompleteListener listener) {
        mContext = context;
        mOnCompleteListener = listener;
        // 获取系统通知服务
        mNotifiManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        // 获取任务管理单例
        mTaskManager = GTaskManager.getInstance();
    }

    /**
     * 取消同步操作
     */
    public void cancelSync() {
        mTaskManager.cancelSync(); // 调用任务管理器的取消同步方法
    }

    /**
     * 发布同步进度消息（支持字符串数组参数）
     * @param message 进度消息内容
     */
    public void publishProgess(String message) {
        publishProgress(new String[]{message}); // 调用父类方法发布进度
    }

    /**
     * 显示同步状态通知
     * @param tickerId 通知标题的资源ID
     * @param content 通知内容文本
     */
    private void showNotification(int tickerId, String content) {
        PendingIntent pendingIntent;
        // 根据通知类型设置不同的点击跳转目标
        if (tickerId != R.string.ticker_success) {
            // 非成功状态跳转到设置界面
            pendingIntent = PendingIntent.getActivity(mContext, 0,
                    new Intent(mContext, NotesPreferenceActivity.class),
                    PendingIntent.FLAG_IMMUTABLE);
        } else {
            // 成功状态跳转到笔记列表界面
            pendingIntent = PendingIntent.getActivity(mContext, 0,
                    new Intent(mContext, NotesListActivity.class),
                    PendingIntent.FLAG_IMMUTABLE);
        }
        // 构建通知对象
        Notification.Builder builder = new Notification.Builder(mContext)
                .setAutoCancel(true)         // 点击后自动清除通知
                .setContentTitle(mContext.getString(R.string.app_name)) // 应用名称作为标题
                .setContentText(content)      // 通知内容
                .setContentIntent(pendingIntent) // 点击通知后的跳转意图
                .setWhen(System.currentTimeMillis()) // 通知时间
                .setOngoing(true);             // 显示为进行中状态（不可滑动清除）
        Notification notification = builder.getNotification();
        // 显示通知
        mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
    }

    /**
     * 后台执行同步操作的核心方法
     * @param unused 未使用的参数（继承自AsyncTask）
     * @return 同步结果状态码（来自GTaskManager的定义）
     */
    @Override
    protected Integer doInBackground(Void... unused) {
        // 发布登录进度消息（包含当前同步账户名）
        publishProgess(mContext.getString(R.string.sync_progress_login,
                NotesPreferenceActivity.getSyncAccountName(mContext)));
        // 调用任务管理器的同步方法，传入上下文和当前任务实例
        return mTaskManager.sync(mContext, this);
    }

    /**
     * 处理进度更新的回调方法（在主线程执行）
     * @param progress 包含进度消息的字符串数组
     */
    @Override
    protected void onProgressUpdate(String... progress) {
        // 显示同步中通知
        showNotification(R.string.ticker_syncing, progress[0]);
        // 如果上下文是同步服务，发送广播通知进度
        if (mContext instanceof GTaskSyncService) {
            ((GTaskSyncService) mContext).sendBroadcast(progress[0]);
        }
    }

    /**
     * 处理后台任务完成的回调方法（在主线程执行）
     * @param result 同步结果状态码
     */
    @Override
    protected void onPostExecute(Integer result) {
        String content;
        int tickerId;
        // 根据不同的同步结果显示对应的通知
        switch (result) {
            case GTaskManager.STATE_SUCCESS:
                tickerId = R.string.ticker_success;
                content = mContext.getString(R.string.success_sync_account,
                        mTaskManager.getSyncAccount()); // 显示成功消息和账户名
                NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); // 记录最后同步时间
                break;
            case GTaskManager.STATE_NETWORK_ERROR:
                tickerId = R.string.ticker_fail;
                content = mContext.getString(R.string.error_sync_network); // 网络错误消息
                break;
            case GTaskManager.STATE_INTERNAL_ERROR:
                tickerId = R.string.ticker_fail;
                content = mContext.getString(R.string.error_sync_internal); // 内部错误消息
                break;
            case GTaskManager.STATE_SYNC_CANCELLED:
                tickerId = R.string.ticker_cancel;
                content = mContext.getString(R.string.error_sync_cancelled); // 取消同步消息
                break;
            default:
                return;
        }
        showNotification(tickerId, content); // 显示结果通知

        // 在后台线程执行回调，避免阻塞主线程
        if (mOnCompleteListener != null) {
            new Thread(new Runnable() {
                public void run() {
                    mOnCompleteListener.onComplete(); // 触发完成回调
                }
            }).start();
        }
    }
}