package com.persagy.functions.weather.business.v2020.discard;

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

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.persagy.core.service.BaseBusinessService;
import com.persagy.core.service.BusinessService;
import com.persagy.ems.pojo.wz.DayHisRecord;
import com.persagy.ems.pojo.wz.DayPredictRecord;
import com.persagy.ems.pojo.wz.HourRecordData;
import com.persagy.framework.util.ConfigUtil;
import com.persagy.framework.util.DateUtils;
import com.persagy.framework.util.WServiceUtil;
import com.persagy.functions.weather.constant.Const;
import com.persagy.functions.weather.dto.DayPredictDTO;
import com.persagy.functions.weather.service.DayHisRecordService;
import com.persagy.functions.weather.service.HourRecordService;

@Service("QueryWeatherService")
@Scope("prototype")
@SuppressWarnings({ "unchecked", "rawtypes" })
public class QueryWeatherService extends BaseBusinessService<Map> implements BusinessService {

	@Resource
	private DayHisRecordService dayHisRecordService;
	@Resource
	private HourRecordService hourDataService;

	@Override
	public void handle(Map dto, List content) throws Exception {
		String name = (String) dto.get("name");
		String projectId = (String) dto.get("projectId");
		String cityCode = (String) dto.get("cityCode");
		
		if ((StringUtils.isEmpty(projectId)) && (StringUtils.isEmpty(cityCode)) && (StringUtils.isEmpty(name))) {
			throw new Exception(Const.ErrorTag.paramMis);
		}
		
		String date = (String) dto.get("date");
		Integer limit = (Integer) dto.get("limit");

		Date startDay = null;
		try {
			startDay = DateUtils.str2Date(date, "yyyy-MM-dd");
		} catch (Exception localException) {
		}
		if (startDay == null) {
			throw new Exception(Const.ErrorTag.paramFormat);
		}
		
		String location = ConfigUtil.getLocationStrict(name, cityCode, projectId);
		
		if (location == null) {
			throw new Exception(Const.ErrorTag.cityNotFound);
		}
		limit = Integer.valueOf(limit == null ? 5 : limit.intValue());
		if (limit.intValue() < 1) {
			return;
		}
		if(limit > 366) {
			throw new Exception(Const.ErrorTag.timeToLong);
		}
		
		Date today = DateUtils.getShortDate(new Date(), 3);

		Date endDay = DateUtils.getDayOff(startDay, limit.intValue());

		Date hisDayStart = null;
		Date hisDayEnd = null;
		Date foreDayStart = null;
		
		if (startDay.before(today)) {
			hisDayStart = startDay;
			if (endDay.compareTo(today) <= 0) {
				hisDayEnd = endDay;
			} else {
				hisDayEnd = today;
				foreDayStart = today;
			}
		}else {
			foreDayStart = today;
		}
		
		Map<String, HourRecordData> hDataMap = new HashMap<>();
		if(!today.before(startDay) && today.before(endDay)) {
			List<HourRecordData> hHisList = hourDataService.query(location, startDay, endDay);
			if(null != hHisList) {
				String dayStr = "";
				for(HourRecordData obj : hHisList) {
					dayStr = DateUtils.date2Str(obj.getHourTime(), "yyyy-MM-dd");
					hDataMap.put(dayStr, obj);
				}
			}
		}
		
		List<Map<String, String>> resultList = new ArrayList();
		if (hisDayStart != null) {
			List<DayHisRecord> histList = this.dayHisRecordService.query(location, hisDayStart, hisDayEnd);
			if (histList != null) {
				for (DayHisRecord obj : histList) {
					Map<String, String> item = new HashMap();
					resultList.add(item);
					item.put("date", DateUtils.date2Str(obj.getDayTime(), "yyyy-MM-dd"));
					item.put("codeDay", obj.getCode_day());
					item.put("code", obj.getCode_day());
					item.put("codeNight", obj.getCode_night());
					item.put("high", obj.getHigh());
					item.put("humidity", obj.getHumidity());
					item.put("low", obj.getLow());
					item.put("textDay", obj.getText_day());
					item.put("text", obj.getText_day());
					item.put("textNight", obj.getText_night());
					item.put("windDirection", obj.getWind_direction());
					item.put("windDirectionDegree", obj.getWind_direction_degree());
					item.put("windScale", obj.getWind_scale());
					item.put("windSpeed", obj.getWind_speed());
					
					HourRecordData hdata = hDataMap.get(item.get("date"));
					if(null != hdata) {
						item.put("text", hdata.getText());
						item.put("code", hdata.getCode());
						item.put("aqi", hdata.getAqi());
						item.put("pm25", hdata.getPm25());
						item.put("pm10", hdata.getPm10());
						item.put("so2", hdata.getSo2());
						item.put("no2", hdata.getNo2());
						item.put("co", hdata.getCo());
						item.put("o3", hdata.getO3());
						item.put("quality", hdata.getQuality());
						item.put("feelsLike", hdata.getFeels_like());
						item.put("temperature", hdata.getTemperature());
						item.put("pressure", hdata.getPressure());
						item.put("visibility", hdata.getVisibility());
					}
					
					if(resultList.size() == limit) {
						break;
					}
				}
			}
		}
		if (foreDayStart != null && resultList.size() < limit) {
			List<DayPredictDTO> preList = new ArrayList<>();
			List<DayPredictRecord> list = dayHisRecordService.queryPredictData(location, 15);
			
			if(null != list) {
				for(DayPredictRecord item : list) {
					DayPredictDTO obj = new DayPredictDTO();
					obj.setDate(DateUtils.date2Str(item.getDayTime(), "yyyy-MM-dd"));
					obj.setCode_day(item.getCode_day());
					obj.setCode_night(item.getCode_night());
					obj.setHigh(item.getHigh());
					obj.setHumidity(item.getHumidity());
					obj.setLow(item.getLow());
					obj.setText_day(item.getText_day());
					obj.setText_night(item.getText_night());
					obj.setWind_direction(item.getWind_direction());
					obj.setWind_direction_degree(item.getWind_direction_degree());
					obj.setWind_scale(item.getWind_scale());
					obj.setWind_speed(item.getWind_speed());
					preList.add(obj);
				}
			}
			
			if(preList.isEmpty()) {
				preList = WServiceUtil.getDayPredictObj(location, 0, 15);
			}
			
			if (preList != null) {
//				Map<String, Object> nowDataMap = new HashMap<>();
//				if(foreDayStart.equals(today)) {
//					nowDataMap.putAll(WServiceUtil.getNowAir(location));
//					nowDataMap.putAll(WServiceUtil.getNowWeather(location));
//				}
//				boolean first = true;
				for (DayPredictDTO obj : preList) {
					Map<String, String> item = new HashMap();
					resultList.add(item);
					item.put("date", obj.getDate());
					item.put("codeDay", obj.getCode_day());
					item.put("codeNight", obj.getCode_night());
					item.put("high", obj.getHigh());
					item.put("humidity", obj.getHumidity());
					item.put("low", obj.getLow());
					item.put("textDay", obj.getText_day());
					item.put("textNight", obj.getText_night());
					item.put("windDirection", obj.getWind_direction());
					item.put("windDirectionDegree", obj.getWind_direction_degree());
					item.put("windScale", obj.getWind_scale());
					item.put("windSpeed", obj.getWind_speed());

					HourRecordData hdata = hDataMap.get(item.get("date"));
					if(null != hdata) {
						item.put("text", hdata.getText());
						item.put("code", hdata.getCode());
						item.put("aqi", hdata.getAqi());
						item.put("pm25", hdata.getPm25());
						item.put("pm10", hdata.getPm10());
						item.put("so2", hdata.getSo2());
						item.put("no2", hdata.getNo2());
						item.put("co", hdata.getCo());
						item.put("o3", hdata.getO3());
						item.put("quality", hdata.getQuality());
						item.put("feelsLike", hdata.getFeels_like());
						item.put("temperature", hdata.getTemperature());
						item.put("pressure", hdata.getPressure());
						item.put("visibility", hdata.getVisibility());
					}
					
					if(resultList.size() == limit) {
						break;
					}
				}
			}
		}
		content.addAll(resultList);
	}
}