package com.gh.gamecenter.manager;

import android.content.Context;

import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.gh.base.AppController;
import com.gh.common.util.DeviceUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.Utils;
import com.gh.gamecenter.db.DataCollectionDao;
import com.gh.gamecenter.db.info.DataCollectionInfo;
import com.gh.gamecenter.volley.extended.JsonObjectExtendedRequest;

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class DataCollectionManager {

	private static DataCollectionManager mInstance;

	private Context mContext;
	private DataCollectionDao dao;

	private DataCollectionManager(Context context) {
		mContext = context;
		dao = new DataCollectionDao(mContext);
		isUploading = false;
	}

	public static DataCollectionManager getInstance(Context context) {
		if (mInstance == null) {
			synchronized (DataCollectionManager.class) {
				if (mInstance == null) {
					mInstance = new DataCollectionManager(
							context.getApplicationContext());
				}
			}
		}
		return mInstance;
	}

	// 添加事件
	public static void onEvent(Context context, DataCollectionInfo entity, boolean isUpload) {
		DataCollectionManager.getInstance(context).add(entity, isUpload);
	}

	public static void onEvent(Context context, String type, String data, boolean isUpload) {
		String id = UUID.randomUUID().toString().replaceAll("-", "");
		DataCollectionInfo entity = new DataCollectionInfo();
		entity.setId(id);
		entity.setType(type);
		entity.setData(data);
		onEvent(context, entity, isUpload);
	}

	public static void onEvent(Context context, String type, Map<String, Object> map) {
		map.put("createdOn", Utils.getTime(context));
		if ("news".equals(type) || "download".equals(type) || "search".equals(type)) {
			DataCollectionManager.getInstance(context).realTimeUpload(type, map);
			return;
		}
		onEvent(context, type, new JSONObject(map).toString(), true);
	}

	public static void onEvent(Context context, String type, Map<String, Object> map, boolean isUpload) {
		map.put("createdOn", Utils.getTime(context));
		onEvent(context, type, new JSONObject(map).toString(), isUpload);
	}

	public static void upsert(Context context, String type, Map<String, Object> map) {
		map.put("createdOn", Utils.getTime(context));
		String id = UUID.randomUUID().toString().replaceAll("-", "");
		DataCollectionInfo entity = new DataCollectionInfo();
		entity.setId(id);
		entity.setType(type);
		entity.setData(new JSONObject(map).toString());
		DataCollectionManager.getInstance(context).upsert(entity, type);
	}

	public void upsert(DataCollectionInfo entity, String type) {
		List<DataCollectionInfo> list = dao.findByType(type);
		if (list == null || list.isEmpty()) {
			dao.add(entity);
		} else {
			entity.setId(list.get(0).getId());
			dao.update(entity);
			if (list.size() > 1) {
				List<String> ids = new ArrayList<>();
				for (int i = 1, size = list.size(); i < size; i++) {
					ids.add(list.get(i).getId());
				}
				dao.delete(ids);
			}
		}
	}

	// 把事件加入列表
	public void add(DataCollectionInfo entity, boolean isUpload) {
		// 加入列表
		dao.add(entity);

		// 检查列表数目是否满足条件
		if (isUpload) {
			 List<DataCollectionInfo> list = dao.getAll();
			 if (list.size() >= 20) {
				 try {
				 	upload(list);
				 } catch (JSONException e) {
					 e.printStackTrace();
				 }
			 }
		}
	}

	/*
	 * 实时上传
	 */
	private void realTimeUpload(String type, Map<String, Object> map) {
		String version = PackageUtils.getVersion(mContext);
		String user = DeviceUtils.getDeviceID(mContext);
		String channel = (String) PackageUtils.getMetaData(mContext,
				mContext.getPackageName(), "TD_CHANNEL_ID");
		map.put("version", version);
		map.put("user", user);
		map.put("channel", channel);
		Map<String, String> params = new HashMap<>();
		params.put("type", type);
		params.put("data", new JSONObject(map).toString());
		String url = "http://data.ghzhushou.com/collection/upload2";
		JSONObject body = new JSONObject(params);
		JsonObjectExtendedRequest request = new JsonObjectExtendedRequest(
				Method.POST, url, body.toString(),
				null, null);
		request.setShouldCache(false);
		AppController.addToRequestQueue(request);
	}

	/*
	 * 统计点击数据
	 */
	public void statClickData() {
		List<DataCollectionInfo> list = dao.getClickData();
		if (!list.isEmpty()) {
			List<String> ids = new ArrayList<>();
			DataCollectionInfo dataCollectionEntity;
			List<Object> data = new ArrayList<>();
			try {
				for (int i = 0, size = list.size(); i < size; i++) {
					dataCollectionEntity = list.get(i);
					ids.add(dataCollectionEntity.getId());
					data.add(new JSONObject(dataCollectionEntity.getData()));
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
			Map<String, Object> map = new HashMap<>();
			map.put("data", data);
			onEvent(mContext, "click", map);
			dao.delete(ids);
		}
	}

	// 上传数据
	public void upload() {
		statClickData();
		List<DataCollectionInfo> list = dao.getAll();
		if (!list.isEmpty()) {
			try {
				upload(list);
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

	private boolean isUploading;

	// 上传数据
	private void upload(List<DataCollectionInfo> list) throws JSONException {
		if (isUploading) {
			return;
		}
		isUploading = true;
		String url = "http://data.ghzhushou.com/collection/upload";

		final List<String> ids = new ArrayList<>();

		String version = PackageUtils.getVersion(mContext);
		String user = DeviceUtils.getDeviceID(mContext);
		String channel = (String) PackageUtils.getMetaData(mContext,
				mContext.getPackageName(), "TD_CHANNEL_ID");

		HashMap<String, JSONArray> map = new HashMap<>();
		DataCollectionInfo dataCollectionEntity;
		String type;
		JSONArray jsonArray;
		for (int i = 0, size = list.size(); i < size; i++) {
			dataCollectionEntity = list.get(i);
			type = dataCollectionEntity.getType();
			if (type.equals("click-item")) {
				continue;
			}
			jsonArray = map.get(type);
			if (jsonArray == null) {
				jsonArray = new JSONArray();
			}
			JSONObject jsonObject = new JSONObject(
					dataCollectionEntity.getData());
			jsonObject.put("version", version);
			jsonObject.put("user", user);
			jsonObject.put("channel", channel);
			jsonArray.put(jsonObject.toString());
			map.put(type, jsonArray);

			ids.add(dataCollectionEntity.getId());
		}

		if (ids.size() < 20) {
			return;
		}

		ArrayList<Object> params = new ArrayList<>();
		for (String key : map.keySet()) {
			HashMap<String, Object> hashMap = new HashMap<>();
			hashMap.put("type", key);
			hashMap.put("data", map.get(key));
			JSONObject jsonObject = new JSONObject(hashMap);
			params.add(jsonObject);
		}
		JSONArray body = new JSONArray(params);

		JsonObjectExtendedRequest request = new JsonObjectExtendedRequest(
				Method.POST, url, body.toString(),
				new Response.Listener<JSONObject>() {
					@Override
					public void onResponse(JSONObject response) {
						isUploading = false;
						Utils.log(response);
						try {
							if ("success".equals(response.getString("status"))) {
								// 上传成功，删除本地数据
								dao.delete(ids);
							}
						} catch (JSONException e) {
							e.printStackTrace();
						}
					}
				}, new Response.ErrorListener() {
					@Override
					public void onErrorResponse(VolleyError error) {
						isUploading = false;
						// 上传失败，检查网络状态，继续上传
						Utils.log(error);
						if (error.networkResponse != null) {
							Utils.log(new String(error.networkResponse.data));
						}
					}
				});
		AppController.addToRequestQueue(request);
	}

}
