package com.zhiwei.manage.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Resource;

import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.connection.Server;
import com.zhiwei.manage.bean.Data;
import com.zhiwei.manage.bean.EasyNews;
import com.zhiwei.manage.bean.News;
import com.zhiwei.manage.bean.ServerBean;
import com.zhiwei.manage.bean.Weibo;
import com.zhiwei.manage.handle.DbDepot;
import com.zhiwei.manage.util.Change;
import com.zhiwei.manage.util.MongoConnect;

@Component
public class DataDaoImpl implements DataDao {

	@Resource(name = "mongoTemplate")
	private MongoTemplate mongo;
	@Resource(name = "newmongoTemplate")
	private MongoTemplate mongo2;
	@Resource(name = "weibomongoTemplate")
	private MongoTemplate weibo;

	@Override
	public List<Data> findByPt(Date startTime, Date endTime, String pt) {
		Criteria criteria = new Criteria();
		criteria.and("pt").is(pt);
		criteria.and("time").gt(startTime).lt(endTime);
		criteria.and("tempName").exists(false);
		return mongo.find(Query.query(criteria), Data.class, "Data");
	}

	@Override
	public List<Data> findBySource(Date startTime, Date endTime, String source) {
		Criteria criteria = new Criteria();
		criteria.and("source").is(source);
		criteria.and("time").gte(startTime).lt(endTime);
		return mongo.find(Query.query(criteria), Data.class, "Data");
	}

	@Override
	public List<Data> findBytempName(Date startTime, Date endTime, String tempName) {
		Criteria criteria = new Criteria();
		criteria.and("tempName").is(tempName);
		criteria.and("time").gte(startTime).lt(endTime);
		return mongo.find(Query.query(criteria), Data.class, "Data");
	}

	@Override
	public void insert(Data data) {
		mongo.insert(data, "Data");
	}

	@Override
	public List<EasyNews> findByAccurateSource(String startTime, String endTime, String source) {
		Calendar c = Calendar.getInstance();
		int month = c.get(Calendar.MONTH) + 1;
		int year = c.get(Calendar.YEAR);
		Criteria criteria = new Criteria();
		criteria.and("source").is(source);
		criteria.and("time").gte(startTime).lt(endTime);
		return mongo2.find(Query.query(criteria), EasyNews.class, "net_media_" + year + (month>10?""+month:"0"+month));
	}

	@Override
	public List<EasyNews> findByAccurateSpId(String startTime, String endTime, String SpId) {
		Calendar c = Calendar.getInstance();
		int month = c.get(Calendar.MONTH) + 1;
		int year = c.get(Calendar.YEAR);
		Criteria criteria = new Criteria();
		criteria.and("spyderInfoId").is(SpId);
		criteria.and("time").gt(startTime).lt(endTime);
		return mongo2.find(Query.query(criteria), EasyNews.class, "net_media_" + year + (month>10?""+month:"0"+month));
	}

	@Override
	public long findWeiboCount(Date startTime, Date endTime) {
		Calendar c = Calendar.getInstance();
		c.setTime(startTime);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return weibo.count(Query.query(Criteria.where("time").gte(sdf.format(startTime)).lt(sdf.format(endTime))),
				Weibo.class, "status_" + year + (month>10?""+month:"0"+month));
	}

	@Override
	@SuppressWarnings("resource")
	public long finCountByDayData(Date startTime, Date endTime, String pt, String id) {
		String end = "";
		Calendar cal = Calendar.getInstance();
		MongoCollection<Document> col = null;
		if (pt.equals("知乎")) {
			if (DbDepot.dataCol != null) {
				if (DbDepot.dataCol.get(pt) != null && DbDepot.month == cal.get(Calendar.MONTH)) {
					col = (MongoCollection<Document>) DbDepot.dataCol.get(pt);
				}
			}
			int resultCount=0;
			if (col == null) {
				ServerBean ser = mongo.findOne(
						Query.query(Criteria.where("pt").is(pt).andOperator(Criteria.where("other").is("data"))),
						ServerBean.class);
				MongoClient mongoClient = new MongoClient(ser.getDbHost(), ser.getDbPort());
				// 连接到数据库
				MongoDatabase mongo = mongoClient.getDatabase(ser.getDbName());
				for (int i = 1; i < 6; i++) {
					col = mongo.getCollection(ser.getCollection() + i);
					Bson query = new BasicDBObject("update_at", new BasicDBObject("$gte", startTime).append("$lte", endTime));
					resultCount+=col.count(query);
				}
			}
			return resultCount;
		}
		if (DbDepot.dataCol != null) {
			if (DbDepot.dataCol.get(pt) != null && DbDepot.month == cal.get(Calendar.MONTH)) {
				col = (MongoCollection<Document>) DbDepot.dataCol.get(pt);
			} else {
				ServerBean ser = mongo.findOne(
						Query.query(Criteria.where("pt").is(pt).andOperator(Criteria.where("other").is("data"))),
						ServerBean.class);
				if (ser.isTable()) {
					int month=cal.get(Calendar.MONTH)+1;
					end = cal.get(Calendar.YEAR) +""+ (month>10?""+month:"0"+month);
					System.out.println(end);
				}
				MongoClient mongoClient = new MongoClient(ser.getDbHost(), ser.getDbPort());
				// 连接到数据库
				MongoDatabase mongo = mongoClient.getDatabase(ser.getDbName());
				col = mongo.getCollection(ser.getCollection() + end);
				DbDepot.dataCol.put(pt, col);
				DbDepot.month = cal.get(Calendar.MONTH);
			}
		} else {
			DbDepot.dataCol = new ConcurrentHashMap<String, Object>();
			ServerBean ser = mongo.findOne(
					Query.query(Criteria.where("pt").is(pt).andOperator(Criteria.where("other").is("data"))),
					ServerBean.class);
			if (ser.isTable()) {
				int month=cal.get(Calendar.MONTH)+1;
				end = cal.get(Calendar.YEAR) +""+ (month>10?""+month:"0"+month);
			}
			MongoClient mongoClient = new MongoClient(ser.getDbHost(), ser.getDbPort());
			// 连接到数据库
			MongoDatabase mongo = mongoClient.getDatabase(ser.getDbName());
			col = mongo.getCollection(ser.getCollection() + end);
			DbDepot.dataCol.put(pt, col);
		}
		long count = 0;
		if (id == null) {
			if (pt.equals("微博")) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
				Bson query = new BasicDBObject("time",
						new BasicDBObject("$gte", sdf.format(startTime)).append("$lte", sdf.format(endTime)));
				count = col.count(query);
			} else if (pt.equals("微信") || pt.equals("网媒") || pt.equals("论坛") || pt.equals("贴吧")||pt.equals("平媒")) {
				Bson query = new BasicDBObject("time", new BasicDBObject("$gte", startTime).append("$lte", endTime))
						.append("pt", pt);
				count = col.count(query);
			} else {
				Bson query = new BasicDBObject("time", new BasicDBObject("$gte", startTime).append("$lte", endTime));
				count = col.count(query);
			}
		} else {
			Bson query = new BasicDBObject("time", new BasicDBObject("$gte", startTime).append("$lte", endTime))
					.append("spyderInfoId", id);
			count = col.count(query);
		}
		System.out.println(count);
		return count;
	}

	public static void main(String[] args) {
		MongoClient mongoClient = new MongoClient("1.119.44.206", 30000);
		// 连接到数据库
		MongoDatabase mongo = mongoClient.getDatabase("wx_tanglihua");
		MongoCollection<Document> col = mongo.getCollection("status_201712");
		Date start = new Date();
		start.setDate(15);
		Date end = new Date();
		end.setDate(16);
		Bson query = new BasicDBObject("time", new BasicDBObject("$gte", start).append("$lte", end));
		System.out.println(col.count(query));
	}

	@Override
	public long findWeixinCount(Date startTime, Date endTime, String pt) {
		MongoCollection<Document> col = null;
		if (DbDepot.newsCol != null) {
			if (DbDepot.newsCol.get(pt) != null) {
				System.out.println("已经有，不重新创建");
				col = (MongoCollection<Document>) DbDepot.newsCol.get(pt);
			} else {
				ServerBean ser = mongo.findOne(Query.query(Criteria.where("pt").is(pt)), ServerBean.class);
				MongoClient mongoClient = new MongoClient(ser.getDbHost(), ser.getDbPort());
				// 连接到数据库
				MongoDatabase mongo = mongoClient.getDatabase(ser.getDbName());
				col = mongo.getCollection(ser.getCollection());
				DbDepot.newsCol.put(pt, col);
			}
		} else {
			DbDepot.newsCol = new ConcurrentHashMap<String, Object>();
			ServerBean ser = mongo.findOne(Query.query(Criteria.where("pt").is(pt)), ServerBean.class);
			MongoClient mongoClient = new MongoClient(ser.getDbHost(), ser.getDbPort());
			// 连接到数据库
			MongoDatabase mongo = mongoClient.getDatabase(ser.getDbName());
			col = mongo.getCollection(ser.getCollection());
			DbDepot.newsCol.put(pt, col);
		}
		Bson query = new BasicDBObject("time", new BasicDBObject());
		long count = col.count(query);
		return count;
	}

	@Override
	public List<EasyNews> findBySourceFromLibrary(Date startTime, Date endTime, String source) {
		Calendar c = Calendar.getInstance();
		c.setTime(startTime);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		return mongo2.find(Query.query(Criteria.where("time").gte(startTime).lt(endTime).and("type").is(source)),
				EasyNews.class, "net_media_" + year + (month>10?""+month:"0"+month));
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<String> findSourceByLikeParam(String param) {
		Calendar c = Calendar.getInstance();
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		try {
			return mongo2.getCollection("net_media_" + year + (month>10?""+month:"0"+month)).distinct("source",
					new BasicDBObject("source", new BasicDBObject("$regex", param)));
		} catch (Exception e) {
			return mongo2.getCollection("net_media_" + year + (month>10?""+month:"0"+month)).distinct("source",
					new BasicDBObject("source", new BasicDBObject("$regex", param)));
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<String> findTmpNameByLikeParam(String param) {
		try {
			return mongo.getCollection("Data").distinct("tempName",
					new BasicDBObject("tempName", new BasicDBObject("$regex", param)));
		} catch (Exception e) {
			return mongo.getCollection("Data").distinct("tempName",
					new BasicDBObject("tempName", new BasicDBObject("$regex", param)));
		}
	}

	@Override
	public List<EasyNews> findByAccurateType(Date startTime, Date endTime, String type) {
		Calendar c = Calendar.getInstance();
		c.setTime(startTime);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		return mongo2.find(Query.query(Criteria.where("time").gte(startTime).lt(endTime).and("type").is(type)),
				EasyNews.class, "net_media_" + year + (month>10?""+month:"0"+month));
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<String> findTypeByLikeParam(String param) {
		Calendar c = Calendar.getInstance();
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		try {
			DBObject obj = new BasicDBObject();
			obj.put("pt", new BasicDBObject("$ne", "微信"));
			obj.put("type", new BasicDBObject("$regex", param));
			return mongo2.getCollection("net_media_" + year + (month>10?""+month:"0"+month)).distinct("type", obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List<Data> findByMethod(Date startTime, Date endTime, String method, Object value) {
		List<Data> list = new ArrayList<Data>();
		if (DbDepot.dbCons.get("data") != null) {
			DBCollection coll = (DBCollection) DbDepot.dbCons.get("data");
			DBObject obj = new BasicDBObject();
			if (method != null) {
				obj.put(method, value);
				obj.put("time", new BasicDBObject("$gte", startTime).append("$lt", endTime));
			} else {
				obj.put("time", new BasicDBObject("$gte", startTime).append("$lt", endTime));
			}
			DBCursor cursor = coll.find(obj).sort(new BasicDBObject("time", -1));
			while (cursor.hasNext()) {
				Map<String, Object> map = (Map<String, Object>) cursor.next();
				Data d = Change.toBean(Data.class, map);
				list.add(d);
			}
			cursor.close();
		} else {
			System.out.println("user------------------");
			ServerBean sb = mongo.findOne(Query.query(Criteria.where("other").is("data")), ServerBean.class);
			DBCollection coll = null;
			if (sb.getDbUsername() == null || sb.getDbUsername().equals("")) {
				coll = new MongoConnect(sb.getDbHost(), sb.getDbPort(), sb.getDbName())
						.getCollection(sb.getCollection());
			} else {
				coll = new MongoConnect(sb.getDbHost(), sb.getDbPort(), sb.getDbUsername(), sb.getDbPassword(),
						sb.getDbName()).getCollection(sb.getCollection());
				DbDepot.dbCons.put(sb.getOther(), coll);
			}
			DBObject obj = new BasicDBObject();
			if (method != null) {
				obj.put(method, value);
				obj.put("time", new BasicDBObject("$gte", startTime).append("$lt", endTime));
			} else {
				obj.put("time", new BasicDBObject("$gte", startTime).append("$lt", endTime));
			}
			DBCursor cursor = coll.find(obj).sort(new BasicDBObject("time", -1));
			while (cursor.hasNext()) {
				Map<String, Object> map = (Map<String, Object>) cursor.next();
				Data d = Change.toBean(Data.class, map);
				list.add(d);
			}
			cursor.close();
		}
		return list;
	}

	@Override
	public List<EasyNews> findBySpId(Date startTime, Date endTime, String syId) {
		Calendar c = Calendar.getInstance();
		c.setTime(startTime);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		return mongo2.find(Query.query(Criteria.where("time").gte(startTime).lt(endTime).and("spyderInfoId").is(syId)),
				EasyNews.class, "net_media_" + year + (month>10?""+month:"0"+month));
	}

}
