package com.cloudcross.ssp.web.advertiser.main.ad.target;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.logging.LogFactory;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cloudcross.ssp.base.web.SimpleController;
import com.cloudcross.ssp.common.utils.AdvertiserSortByDate;
import com.cloudcross.ssp.common.utils.Common;
import com.cloudcross.ssp.common.utils.Pager;
import com.cloudcross.ssp.common.utils.Pager1;
import com.cloudcross.ssp.model.Account;
import com.cloudcross.ssp.model.AdGroup;
import com.cloudcross.ssp.model.AdGroupPlace;
import com.cloudcross.ssp.model.DayParting;
import com.cloudcross.ssp.model.Direct;
import com.cloudcross.ssp.model.Location;
import com.cloudcross.ssp.model.Log;
import com.cloudcross.ssp.model.Operator;
import com.cloudcross.ssp.model.Place;
import com.cloudcross.ssp.model.PlaceClassInformation;
import com.cloudcross.ssp.model.PlaceOperator;
import com.cloudcross.ssp.model.Wifi;
import com.cloudcross.ssp.model.Zone;
import com.cloudcross.ssp.model.pojo.CampaignPojo;
import com.cloudcross.ssp.service.IAdGroupPlaceService;
import com.cloudcross.ssp.service.IAdGroupService;
import com.cloudcross.ssp.service.ICampaignService;
import com.cloudcross.ssp.service.IDirectService;
import com.cloudcross.ssp.service.ILocationService;
import com.cloudcross.ssp.service.ILogService;
import com.cloudcross.ssp.service.IOperatorService;
import com.cloudcross.ssp.service.IPlaceClassInformationService;
import com.cloudcross.ssp.service.IPlaceOperatorService;
import com.cloudcross.ssp.service.IPlaceService;
import com.cloudcross.ssp.service.IWifiService;
import com.cloudcross.ssp.service.IZoneService;

@Controller
@RequestMapping("/advertiser/main/ad/target/ad-group-alloperator")
public class AdGroupAlloperatorController extends SimpleController{
	private static final Logger LOG = Logger.getLogger(AdGroupAlloperatorController.class);
	@Autowired
	private ICampaignService campaignService;
	@Autowired
	private ILocationService locationService;
	@Autowired
	private IOperatorService operatorService;
	@Autowired
	private IPlaceOperatorService placeOperatorService;
	@Autowired
	private IPlaceClassInformationService placeClassInformationService;
	@Autowired
	private IPlaceService placeService;
	@Autowired
	private IWifiService wifiService;
	@Autowired
	private IZoneService zoneService;
	@Autowired
	private ILogService logService;
	@Autowired
	private IAdGroupService adGroupService;
	@Autowired
	private IDirectService directService;
	
	@RequestMapping("create")
	public String create(Model model, @RequestParam Long campaignId) {
		Account account = getLoginUser();
		Long operatorId = account.getOperatorId();
		
		Map<String,Object> condition = new HashMap<String,Object>();
		condition.put("operatorId", operatorId);
		List<Integer> positionList = new ArrayList<Integer>();
		positionList.add(1);
		condition.put("positionList", positionList);
		CampaignPojo campaign = campaignService.findCampaignById(campaignId);
		
		model.addAttribute("campaignId", campaignId);
		model.addAttribute("advertiserId", campaign.getAdvertiserId());	
		model.addAttribute("orderId", campaign.getOrderId());
		model.addAttribute("agentId", campaign.getAgentId());
		model.addAttribute("budget", campaign.getTotalBudget());
		return page("create");
	}
	
	/**
	 * 选择广告位
	 * @param model
	 * @param operatorId 运营商ID {id1，id2，id3，...}
	 * @param position 位置{position1,position2,position3,...}
	 * @return
	 */
	@RequestMapping("chooseZone")
	@ResponseBody
	public List<Zone> queryZoneByCondition(String operatorId,String position){
		Map<String,Object> condition = new HashMap<String,Object>();
		//处理operatorID
		if(operatorId != null && !"".equals(operatorId)){
			condition.put("operatorId", operatorId);
		}
		//处理position
		if(position != null && !"".equals(position)){
			condition.put("position", position);
		}
		if(condition.size() == 0){
			//没有条件是什么都不查
			return new ArrayList<Zone>();
		}
		List<Zone> zoneList = this.zoneService.queryZone(condition);
		return zoneList;
	}
	/**
	 * 到选择媒体弹窗
	 * 创建人：周俊
	 * 创建时间：2015.12.11 17：00
	 * @return
	 */
	@RequestMapping("chooseOperator")
	public String chooseOperatorWindow(Model model,@RequestParam(defaultValue = "1") int page){
		Integer count = this.operatorService.queryAllOperatorCount();
		Pager1 pager = new Pager1();
		pager.setPage(page);
		pager.setTotalRow(count);
		
		Map<String,Object> condition = new HashMap<String,Object>();
		condition.put("pager", pager);
		List<Operator> list = this.operatorService.queryAllOperator(condition);
		model.addAttribute("operatorList", list);
		model.addAttribute("pager", pager);
		return page("operatorWindow");
	}
	
	
	/**
	 * 选择媒体场景
	 * 创建人：周俊
	 * 创建时间：2015.12.11 17：52
	 * 每个运营商场景显示：{场景ID，运营商名+运营商场景，数聚小场景}即：{id,getOperatorShowName(),placeId}其中placeId要传到后台
	 * @return
	 */
	@RequestMapping("chooseOperatorPlace")
	public String chooseOperatorPlaceWindow(Model model,@RequestParam(defaultValue = "1") int page){
		Integer count = this.placeOperatorService.queryOperatorPlaceCount();
		Pager1 pager = new Pager1();
		pager.setPage(page);
		pager.setTotalRow(count);
		
		Map<String,Object> condition = new HashMap<String,Object>();
		condition.put("pager", pager);
		List<PlaceOperator> list = this.placeOperatorService.queryOperatorPlace(condition);
		model.addAttribute("pager", pager);
		model.addAttribute("list", list);
		return page("operatorPlaceWindow");
	}
	
	/**
	 * 选择大场景
	 * 创建人：周俊
	 * 创建时间：2015-12-14 11.30
	 * @param model
	 * @param page
	 * @return
	 */
	@RequestMapping("choosePlaceClass")
	public String choosePlaceClassWindow(Model model,@RequestParam(defaultValue = "1") int page){
		Integer count = this.placeClassInformationService.queryPlaceClassCount();
		Pager1 pager = new Pager1();
		pager.setPage(page);
		pager.setTotalRow(count);
		
		Map<String,Object> condition = new HashMap<String,Object>();
		condition.put("pager", pager);
		List<PlaceClassInformation> list = this.placeClassInformationService.queryPlaceClass(condition);
		model.addAttribute("pager", pager);
		model.addAttribute("list", list);
		return page("placeClassWindow");
	}
	
	/**
	 * 选择小场景
	 * @param model
	 * @param page
	 * @return
	 */
	@RequestMapping("choosePlace")
	public String choosePlaceWindow(Model model,@RequestParam(defaultValue = "1") int page){
		Integer count = this.placeService.queryPlaceCount();
		Pager1 pager = new Pager1();
		pager.setPage(page);
		pager.setTotalRow(count);
		
		Map<String,Object> condition = new HashMap<String,Object>();
		condition.put("pager", pager);
		List<Place> list = this.placeService.queryPlace(condition);
		model.addAttribute("pager", pager);
		model.addAttribute("list", list);
		return page("placeWindow");
	}
	
	/**
	 * 选择终端
	 * @param model
	 * @param page
	 * @param cnCity
	 * @param cn
	 * @return
	 */
	@RequestMapping("chooseWifi")
	public String chooseWifiWindow(Model model,@RequestParam(defaultValue = "1") int page,String cnCity,String cn){
		Map<String,Object> condition = new HashMap<String,Object>();
		if( null != cnCity && !"".equals(cnCity)){
			condition.put("cnCity", cnCity);
		}else{
			cnCity = "市";
		}
		if( null != cn && !"".equals(cn)){
			condition.put("cn", cn);
		}else{
			cn = "省";
		}
		
		Integer count = this.wifiService.queryWifiCount(condition);
		Pager pager = new Pager();
		pager.setPage(page);
		pager.setTotalRow(count);
		
		condition.put("pager", pager);
		List<Wifi> list = this.wifiService.queryWifi(condition);
		model.addAttribute("pager", pager);
		model.addAttribute("cnCity", cnCity);
		model.addAttribute("cn", cn);
		model.addAttribute("list", list);
		return page("wifiWindow");
	}
	
	/**
	 * 查找所有的省
	 * @return
	 */
	@RequestMapping("/cn")
	public @ResponseBody
	Map<String, List<String>> findAllProvince() {
		List<String> provinceList = locationService.findAllProvince();
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		map.put("province", provinceList);
		return map;
	}
	
	/**
	 * 查找该省下的所有城市
	 * @param province
	 * @return
	 */
	@RequestMapping("/city")
	public @ResponseBody
	Map<String, List<String>> findCityByProvince(@RequestParam String province) {
		//这里如果传递过来的参数是空值或者空字符串则返回一个空值
		if(null == province || "".equals(province)) {
			System.out.println("传递的参数出错");
			return null;
		}
		
		try {
			province = new String(province.getBytes("ISO-8859-1"),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		List<String> cityList = locationService.findCityByProvince(province);
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		map.put("city", cityList);
		return map;
	}
	

	/**
	 * 保存方法
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/save")
	public String save(HttpServletRequest request, Model model,@ModelAttribute("form") AdGroup adGroup
			,@RequestParam String areas,@RequestParam Map<String, Object> paramMap) {
		adGroup.setStatus(0);
		
		/**
		 * 在这里做时间定向的功能处理
		 */
		//将前台转换的排期数据转换成需要存储的数据--选择的时间段，以及未选择时间段按照策略的曝光率
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		
		//把投放日期进行转换
    	String activeTime = (String) paramMap.get("activeTime");
		String[] tmpDate = activeTime.split("to");
		String startDateFront = tmpDate[0].trim();
		String endDateFront = tmpDate[1].trim();			
		try {
			adGroup.setStartDate(sdf.parse(startDateFront));
		} catch (ParseException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		try {
			adGroup.setEndDate(sdf.parse(endDateFront));
		} catch (ParseException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}	
		
		//先获得策略的投放周期
		Date startDate = adGroup.getStartDate();
		Date endDate = adGroup.getEndDate();
		//获得前端传递过来的已选择时间段
		String sdayParting = (String)paramMap.get("sdayParting");
		//用来存储转换结果的JSONArray
		JSONArray result = new JSONArray();
		//用来存储传过来时间段信息集合
		List<DayParting> dayList = new ArrayList<DayParting>();    
		//用来存储没选的时间段信息
		List<DayParting> daySurplus = new ArrayList<DayParting>();
		//默认24个时间点
		String allHours = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
		
		  try {
			    //传过来已选择的时间JSONArray
				JSONArray jsonArray = new JSONArray(sdayParting);
				//当没选一个时间段时，默认从开始时间段到结束时间段都为默认曝光上限
				if(jsonArray.length() == 0){                           				
					JSONObject object = new JSONObject();
					object.put("startDate", sdf.format(startDate));
					object.put("endDate", sdf.format(endDate));
					object.put("dehours",allHours);
					result.put(object);
				}
				
				for (int i = 0; i < jsonArray.length(); i++) {
					JSONObject object = jsonArray.getJSONObject(i);
					DayParting day = new DayParting();
					
					//如果传过来的dehours是-1或空或者是空字符串，表示全选
					if(null == object.get("dehours") || "-1".equals(String.valueOf(object.getString("dehours"))) ||
							"".equals(String.valueOf(object.getString("dehours")))) {
						day.setDehours(allHours);
					} else {
						day.setDehours(object.getString("dehours"));
					}
					
					try {
						day.setStartDate(sdf.parse(object.getString("startDate")));
						day.setEndDate(sdf.parse(object.getString("endDate")));
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					dayList.add(day);
				}
				
				//按照开始时间的先后顺序给dayList进行排序，排序后，比较相邻的2个时间段，能够得出未选择的时间段
				Collections.sort(dayList, new AdvertiserSortByDate());
				
				for(int i = 0; i < dayList.size(); i++){
					DayParting dayP = dayList.get(i);
					JSONObject object = new JSONObject();
					object.put("startDate", sdf.format(dayP.getStartDate()));
					object.put("endDate", sdf.format(dayP.getEndDate()));
					//将已选择的时间段放入result中
					object.put("dehours",dayP.getDehours());
					result.put(object);
					
					//当只选择一个时间段时，无法对前后两段时间进行比较，需特殊处理
					if(dayList.size() == 1){
						//所选时间段在开始时间之后--在开始时间到所选时间段中间有空缺时间段
						if(dayP.getStartDate().getTime() > startDate.getTime()){                     
							DayParting dayS = new DayParting();
							dayS.setStartDate(startDate);
							//减一天
							dayS.setEndDate(new Date(dayP.getStartDate().getTime() - 24*60*60*1000));
							dayS.setDehours(allHours);
							daySurplus.add(dayS);
						}
						//所选时间段在开始时间之前--在结束时间到所选时间段中间有空缺时间段
						if(dayP.getEndDate().getTime() < endDate.getTime()){						
							DayParting dayS = new DayParting();
							//加一天
							dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));      
							dayS.setEndDate(endDate);
							dayS.setDehours(allHours);
							daySurplus.add(dayS);
						}
						break;
					}
					
					//排序后的第一条记录，与开始时间比较，得出在开始时间到第一条记录之间是否有空缺时间段
					if(i==0){
						//第一条记录的开始时间大于策略开始时间
						if(dayP.getStartDate().getTime() > startDate.getTime()){     
							DayParting dayS = new DayParting();
							dayS.setStartDate(startDate);
							dayS.setEndDate(new Date(dayP.getStartDate().getTime() - 24*60*60*1000));
							dayS.setDehours(allHours);
							//添加第一条记录开始时间到策略开始时间的空缺段到daySurplus中
							daySurplus.add(dayS);																
							//与后面的一条记录做比较，前一条记录的结束时间小于后一条记录的开始时间，中间有空缺时间段
							DayParting nextDay = dayList.get(i + 1);								
							if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
								DayParting dayS2 = new DayParting();
								dayS2.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
								dayS2.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
								dayS2.setDehours(allHours);
								daySurplus.add(dayS2);
							}
						}else{
							//与后面的一条记录做比较，前一条记录的结束时间小于后一条记录的开始时间，中间有空缺时间段
							DayParting nextDay = dayList.get(i + 1);							
							if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
								DayParting dayS = new DayParting();
								dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
								dayS.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
								dayS.setDehours(allHours);
								daySurplus.add(dayS);
							}
						}
					}else if(i == dayList.size() - 1){		
						//最后一条记录的结束时间小于策略结束时间，中间有空缺时间段
						if(dayP.getEndDate().getTime() < endDate.getTime()){
							DayParting dayS = new DayParting();
							dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
							dayS.setEndDate(endDate);
							dayS.setDehours(allHours);
							daySurplus.add(dayS);
						}
					} else{
						DayParting nextDay = dayList.get(i + 1);				//与后面的一条记录做比较，前一条记录的结束时间小于后一条记录的开始时间，中间有空缺时间段
						if(dayP.getEndDate().getTime() < nextDay.getStartDate().getTime() - 24*60*60*1000){
							DayParting dayS = new DayParting();
							dayS.setStartDate(new Date(dayP.getEndDate().getTime() + 24*60*60*1000));
							dayS.setEndDate(new Date(nextDay.getStartDate().getTime() - 24*60*60*1000));
							dayS.setDehours(allHours);
							daySurplus.add(dayS);
						}
					}
				}
				
				//将空缺时间段添加到result中
				for(int i = 0; i < daySurplus.size(); i++){						
					DayParting dayP = daySurplus.get(i);
					JSONObject object = new JSONObject();
					object.put("startDate", sdf.format(dayP.getStartDate()));
					object.put("endDate", sdf.format(dayP.getEndDate()));
					object.put("dehours",dayP.getDehours());
					result.put(object);
				}
				
				//将已处理的时间段存储起来
				paramMap.put("dayParting", result.toString());					
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				LOG.info("@@@@@@@@排期日期解析错误");
				e.printStackTrace();
			}
		    // 千次转换
		    if (adGroup.getMaxImpression() != null) {
		      adGroup.setMaxImpression(adGroup.getMaxImpression() * 1000);
		    }
		    if (adGroup.getDailyMaxImpression() != null) {
		      adGroup.setDailyMaxImpression(adGroup.getDailyMaxImpression() * 1000);
		    }
			
		    
	    if (adGroup.getId() == null) {	
	    	try {
	    		if (getLoginUser().getOperatorId()!=0) {
					adGroup.setOperatorId(getLoginUser().getOperatorId());
				}else{
					adGroup.setOperatorId(new Long(0));
				}
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
	    	
			adGroupService.saveAllOperator(adGroup, paramMap);
			/**
			 * 新增投放成功后同时会新增地域定向，时段定向,wifi定向以及下面的场景
			 * 所以这里的日志新增记录应该把这些都加进去
			 */
			/**
			 * 先做投放的新增记录
			 */
			Log log = new Log();
			//对应模块
			log.setModule("AdGroup");
			//对应表名
			log.setTableName("t_adgroup");
			//增加对应的投放id
			log.setRecordId(adGroup.getId());
			//对应操作类型
			log.setActionType("新增");
			//对应的操作
			String str = "新增一个投放为："+adGroup.getAdGroupName();
			/*String place = String.valueOf(paramMap.get("place"));
			if(place != null && !"".equals(place)){
				str = str + "；添加了场景为："+place;
			}*/
			log.setAction(str);
			//下面这几个字段目前后端数据没有得到。所以仅作测试用！
			log.setActionTime("100");
			log.setAccountId(new Long(getLoginUser().getId()));
			log.setUserIp(Common.toIpAddr(request));
			log.setAccountName(getLoginUser().getAccountName());
			logService.add(log);
		} 
	    
		model.addAttribute("campaignId", adGroup.getCampaignId());
		return OK;
	}
	
}
