package com.persagy.functions.weather.business.v2021;

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

import org.springframework.stereotype.Service;

import com.persagy.core.enumeration.SpecialOperator;
import com.persagy.framework.construct.RequestProcessor;
import com.persagy.framework.dto.DataQueryParam;
import com.persagy.framework.util.ConfigUtil;
import com.persagy.framework.util.DateUtils;
import com.persagy.framework.util.SunComputeUtil;
import com.persagy.functions.weather.constant.Const;
import com.persagy.functions.weather.dto.CityDTO;

/**
 * 日出日落数据
 */
@Service("sunRiseSet")
public class ComputeSunRiseSet implements RequestProcessor {

	@Override
	public Object handle(DataQueryParam param) throws Exception {
		List<Map<String, Object>> resultList = new ArrayList<>();
		
		Map<String, Object> paramMap = analysisParam(param);
		Date dayStart = (Date) paramMap.get("dayStart");
		Date dayEnd = (Date) paramMap.get("dayEnd");
		Double longitude = (Double) paramMap.get("longitude");
		Double latitude = (Double) paramMap.get("latitude");
		
		Date dayIndex = dayStart;
		do {
			Map<String, Object> item = new HashMap<>();
			item.put("sunRise", SunComputeUtil.getSunrise(longitude, latitude, dayIndex));
			item.put("sunSet", SunComputeUtil.getSunset(longitude, latitude, dayIndex));
			resultList.add(item);
			dayIndex = DateUtils.getDayOff(dayIndex, 1);
		}while(dayIndex.before(dayEnd));
		
		return resultList;
	}
	
	private Map<String, Object> analysisParam(DataQueryParam param) throws Exception {
		Map<String, Object> result = new HashMap<>();
		
		String cityName = param.cityName;
		String cityCode = param.cityCode;
		String projectId = param.projectId;
		Double longitude = param.longitude;
		Double latitude = param.longitude;
		Date dayStart = param.timeSpan.timeLeft;
		Date dayEnd = param.timeSpan.timeRight;
		if(param.timeSpan.optLeft == SpecialOperator.$gt) {
			dayStart = DateUtils.getDayOff(dayStart, 1);
		}
		if(param.timeSpan.optRight == SpecialOperator.$lte) {
			dayEnd = DateUtils.getDayOff(dayEnd, 1);
		}
		
		if(null != cityCode && cityCode.length() != 6) {
			throw new Exception(Const.ErrorTag.paramUnrecognized + " : cityCode="+cityCode);
		}
		
		if(null != projectId && projectId.length() != 12) {
			throw new Exception(Const.ErrorTag.paramUnrecognized + " : projectId="+projectId);
		}
		
		if((longitude != null) ^ (latitude != null)) {
			throw new Exception(Const.ErrorTag.paramMis + " longitude or latitude");
		}
		
		if(!param.timeSpanCheck(366)) {
			throw new Exception(Const.ErrorTag.timeToLong);
		}
		
		result.put("dayStart", dayStart);
		result.put("dayEnd", dayEnd);
		
		if(longitude != null) {
			result.put("longitude", longitude);
			result.put("latitude", latitude);
		}else {
			CityDTO cityInfo = ConfigUtil.dicCityObjMap().get(cityCode);
			if(null == cityInfo && projectId != null) {
				cityInfo = ConfigUtil.dicCityObjMap().get(projectId.substring(2, 8));
			}
			
			if(null == cityInfo && cityName != null) {
				cityInfo = ConfigUtil.dicCityObjMap().get(ConfigUtil.dicName2DicCodeMap().get(cityName));
				
				if(null == cityInfo) {
					for(String name : ConfigUtil.dicName2DicCodeMap().keySet()) {
						if(name.startsWith(cityName) || cityName.startsWith(name)) {
							cityInfo = ConfigUtil.dicCityObjMap().get(ConfigUtil.dicName2DicCodeMap().get(name));
							break;
						}
					}
				}
			}
			
			if(null == cityInfo || cityInfo.getLongitude() == null || cityInfo.getLatitude() == null) {
				throw new Exception(Const.ErrorTag.cityUnsupport);
			}
			
			result.put("longitude", Double.parseDouble(cityInfo.getLongitude()));
			result.put("latitude", Double.parseDouble(cityInfo.getLatitude()));
		}
		
		return result;
	}
}