package com.cloudcross.ssp.service.impl;



import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.cloudcross.ssp.model.Advertiser;
import com.cloudcross.ssp.service.IAdGroupService;
import com.cloudcross.ssp.service.IAdvertiserService;
import com.cloudcross.ssp.service.IBannerService;
import com.cloudcross.ssp.service.ICampaignService;
import com.cloudcross.ssp.service.IOrderService;
import com.cloudcross.ssp.base.dao.GenericIBatisDao;
import com.cloudcross.ssp.base.web.SimpleController;
import com.cloudcross.ssp.base.web.result.AjaxResult;
import com.cloudcross.ssp.common.Config;
import com.cloudcross.ssp.common.utils.Assert;
import com.cloudcross.ssp.common.utils.MapBuilder;
import com.cloudcross.ssp.common.utils.Pager;
import com.cloudcross.ssp.common.utils.SqlHelper;
import com.cloudcross.ssp.web.widget.SelectorController.ISelector;
import com.cloudcross.ssp.web.widget.SelectorController.ISelectorProvider;


@Service
public class AdvertiserService implements IAdvertiserService, ISelectorProvider{

	@Autowired
	private GenericIBatisDao myBatisDao;
	@Autowired
	private IOrderService orderService;
	@Autowired
	private ICampaignService campaignService;
	@Autowired
	private IAdGroupService adGroupService;
	@Autowired
	private IBannerService bannerService;
	@Autowired
	Config config;
	/****************************************************************************/
	//文件系统可上传的文件后缀集合
	private static Set<String> noStuffixSet = new HashSet<String>();
	
	//初始化可上传文件后缀
	static {
		noStuffixSet.add("jpg");
		noStuffixSet.add("png");
		noStuffixSet.add("pdf");
		noStuffixSet.add("doc");
		noStuffixSet.add("docx");
		noStuffixSet.add("xlsx");
		noStuffixSet.add("xls");
	}
	/****************************************************************************/
	
	@Override
	public Advertiser findById(Long id) {
		return myBatisDao.get("advertiserSqlMapper.selectById", id);
	}
	@Override
	public long findByName(String name) {	
		return myBatisDao.get("advertiserSqlMapper.selectByName", name);
	}
	@Override
	public int countByParams(Map<String, Object> paramMap) {
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("value", searchValue);
		return myBatisDao.get("advertiserSqlMapper.countByParams", paramMap);
	}
	public int countByParamsOperator(Map<String, Object> paramMap) {
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		return myBatisDao.get("advertiserSqlMapper.countByParamsoperator", paramMap);
	}
	

	@Override
	public List<Advertiser> findByParams(Map<String, Object> paramMap,Pager pager) {
		//根据广告主的名字模糊查询
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		//paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		paramMap.put("pager", pager);
		return myBatisDao.getList("advertiserSqlMapper.selectByParams", paramMap);
	}
	
	public List<Advertiser> findByParamsBack(Map<String, Object> paramMap,
			Pager pager) {
		// TODO Auto-generated method stub
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		paramMap.put("pager", pager);
		return myBatisDao.getList("advertiserSqlMapper.selectByParamsback", paramMap);
	}
	
	public List<Advertiser> findByParamsOperator(Map<String, Object> paramMap,
			Pager pager) {
		// TODO Auto-generated method stub
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		paramMap.put("pager", pager);
		return myBatisDao.getList("advertiserSqlMapper.selectByParamsoperator", paramMap);
	}
	
	public List<Advertiser> findByOperator(Long operatorId){
		//通过  操作人的 Id 来查找其对应的广告主
		return myBatisDao.getList("selectByOperatoradvertiser", operatorId);
	}
	public List<Advertiser> findByOperatorOperator(Long operatorId){
		//通过  操作人的 Id 来查找其对应的广告主
		return myBatisDao.getList("advertiserSqlMapper.selectByOperatoroperator", operatorId);
	}
	
	@Override
	public boolean add(Advertiser t) {
		t.setUpdated(new Date());
		t.setAdminId(0L);//和权限相关，保存代理商给广告主分配的账号ID，添加时默认为0L
		myBatisDao.save("advertiserSqlMapper.addAdvertiser", t);
		return true;
	}
	
	public boolean addBack(Advertiser t) {
		// TODO Auto-generated method stub
		//————————————————————————————这个地方要注意一点，operator_id并没有插进去！后面需要做完善的！——————————————————————————————————————————
		t.setUpdated(new Date());
//		t.setIndustryId(new Long(1));//由于下拉框的功能还没有完善，测试用。
		myBatisDao.save("advertiserSqlMapper.addAdvertiserback", t);
		
		return true;
	}
	
	public boolean editOperator(Advertiser t) {
		// TODO Auto-generated method stub
		t.setUpdated(new Date());
		myBatisDao.save("advertiserSqlMapper.addAdvertiseroperator", t);
		return true;
	}

	@Override
	public boolean edit(Advertiser t) {
		t.setUpdated(new Date());
		myBatisDao.save("advertiserSqlMapper.editAdvertiser", t);
		return true;
	}
	
	public boolean editBack(Advertiser t) {
		// TODO Auto-generated method stub
		t.setUpdated(new Date());
		myBatisDao.save("advertiserSqlMapper.editAdvertiserback", t);
		return true;
	}

	@Override
	public boolean updateStatus(List<Long> advertiserIdList, int status) {
		// TODO Auto-generated method stub
		myBatisDao.save("advertiserSqlMapper.updateAdvertiserStatus",
				MapBuilder.create(HashMap.class)
					.add("advertiserIdList", advertiserIdList)
					.add("modifyDate", new Date())
					.add("status", status).map());
		return true;
	}
	@Override
	public boolean updateSupdated(List<Long> advertiserIdList, int status) {
		myBatisDao.save("advertiserSqlMapper.updateSupdated",
				MapBuilder.create(HashMap.class)
					.add("advertiserIdList", advertiserIdList)
					.add("modifyDate", new Date())
					.add("status", status).map());
		return true;
	}

	@Override
	public Map<String, List<? extends ISelector>> provideData(String[] parentId) {
		// TODO Auto-generated method stub
		Assert.isTrue(ArrayUtils.isNotEmpty(parentId));
		String operaterId = parentId[0];
		List<Advertiser> advertiserList = findByAgentId(Long.parseLong(operaterId));
		return MapBuilder.create(HashMap.class).add("advertiserList", advertiserList)
				.map();
	}

	@Override
	public int countByStatus(Map<String, Object> paramMap) {
		// TODO Auto-generated method stub
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		return myBatisDao.get("advertiserSqlMapper.countByStatus", paramMap);
	}

	@Override
	public List<Advertiser> findByStatus(Map<String, Object> paramMap) {
		// TODO Auto-generated method stub
		String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
		paramMap.put("key", paramMap.get("searchKey"));
		paramMap.put("value", searchValue);
		return myBatisDao.getList("advertiserSqlMapper.selectByStatus", paramMap);
	}

	
	@Override
	public List<Advertiser> findByAgentId(Long id) {
		// TODO Auto-generated method stub
		return myBatisDao.getList("advertiserSqlMapper.selectByAgentId", id);
	}
	@Override
	public List<Advertiser> findDeliverEffectAnalysis(
			Map<String, Object> paramMap) {
		return myBatisDao.getList("advertiserSqlMapper.findDeliverEffectAnalysis", paramMap);
	}
	
	
	/****************************************************************************/
	public @ResponseBody AjaxResult fileUpload(HttpServletRequest request,HttpServletResponse response) {
		Map<String,String>map = new HashMap<String,String>();
		AjaxResult 	result = new AjaxResult();
		
		try {
			// 创建一个通用的多部分解析器
			CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
			// 判断 request 是否有文件上传,即多部分请求
			if (multipartResolver.isMultipart(request)) {
				// 转换成多部分request
				MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
				// 取得request中的所有文件名
				Iterator<String> iter = multiRequest.getFileNames();
				// 取得上传文件
				MultipartFile file = multiRequest.getFile(iter.next());
				
				if (file != null && file.getSize() >= 0) {
					if (file.getSize() > 32505856) {
						result.setStatus(SimpleController.ERROR);
						result.setMsg("上传文件过大!");
						return result;
					}
				// 取得当前上传文件的文件名称
				String myFileName = file.getOriginalFilename();
				// 获取文件后缀
				String filetype = myFileName.substring(myFileName.lastIndexOf(".") + 1);
				// 如果所属后缀为不可上传后缀，则返回
				if (!noStuffixSet.contains(filetype.trim().toLowerCase())) {
					result.setStatus(SimpleController.ERROR);
					result.setMsg("文件类型不支持!");
					return result;
				}
				String fileId = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
				String folder = getFilePath(request);
				String path = folder+File.separator+fileId+"."+filetype;
				String smallName = fileId+"_small"+"."+filetype;
				String smallPath = folder+File.separator+smallName;
				File distFile = new File(path);
				if (!distFile.getParentFile().exists()){
					distFile.getParentFile().mkdirs();
				}		
					
					file.transferTo(distFile);
					smallPicture(distFile,smallPath,smallName);
					String str = path.substring(path.indexOf("upload")-1)+","+smallPath.substring(path.indexOf("upload")-1);
					result.setStatus(SimpleController.OK);
					result.addData("url", str);
				} else {
					result.setStatus(SimpleController.ERROR);
					result.setMsg("上传文件不能为空!");
					return result;
				}
			}
		} catch (Exception e) {
			result.setStatus(SimpleController.ERROR);
			result.setMsg("上传文件出现异常!");
			return result;
		}
		return result;
	}
	
	//生成缩略图
	public void smallPicture(File sourceFile,String pathSmall,String uploadName) throws IOException{
		//新建缩略图文件
		File smallFile = new File(pathSmall);
		if (!smallFile.getParentFile().exists()){
			smallFile.getParentFile().mkdirs();
		}	
		//构造image图片
		Image src = javax.imageio.ImageIO.read(sourceFile);
		//表示该图像具有打包成整数的像素的8 位RGB颜色分量
		BufferedImage tag = new BufferedImage(150, 60, BufferedImage.TYPE_INT_BGR);
		//h绘制缩小后的图片
		tag.getGraphics().drawImage(src, 0, 0, 150, 60, null);
		//生成缩略图
		ImageIO.write(tag, "jpg", smallFile);
	}
	
	private String getFilePath(HttpServletRequest request){
		// 获取当前上传的年月日
		Calendar cal = Calendar.getInstance();
		// 当前年
		int year = cal.get(Calendar.YEAR);
		// 当前月
		int month = cal.get(Calendar.MONTH) + 1;
		// 当前日
		int day = cal.get(Calendar.DATE);
		//获取文件上传目录
		//获取项目目录
		String realPath = request.getSession().getServletContext().getRealPath("/");
		//获取项目的同级目录
		String root = new File(realPath).getParentFile().getAbsolutePath();
		//到配置文件中获取文件存放的目录
		String upload = config.getResourceUploadDir();
		String path = root+File.separator+upload+File.separator+"advertiser"+File.separator+year + File.separator + month + File.separator + day;
		return path;
	}
	@Override
	public String selectAdvertiserNameById(Long id) {
		// TODO Auto-generated method stub
		return myBatisDao.get("advertiserSqlMapper.selectAdvertiserNameById", id);
	}

	/**
	 * 创建人：周俊
	 * 创建时间：2015.10.19 16.35
	 * 修改广告主的状态，更新他的所有创意，投放的supdate位系统当前时间
	 */
	@Override
	public boolean updateSupdatedAll(List<Long> advertiserIdList, Date date) {
		List<Long>list = new ArrayList<Long>();
		//更新广告主的所有投放的supdate
		 Boolean adGroupFlag = this.adGroupService.updateSupdatedByAdvertiserId(advertiserIdList, date);
		for(Long l:advertiserIdList){
			list.addAll(adGroupService.findAllAdGroudByAdvertiserId(l));
		}
		
		Boolean bannerFlag = false;
		if(list.size()>0){
			bannerFlag = this.bannerService.updateSupdated(list, date);
		}else{
			bannerFlag = true;
			System.out.println("投放下没有创意");
		}
		
		return adGroupFlag&&bannerFlag;
	}
	@Override
	public boolean updateStatusAll(List<Long> advertiserIdList, int status) {
		List<Long>list = new ArrayList<Long>();
		Boolean advertiserFlag = updateStatus(advertiserIdList, status);
		Boolean orderFlag = this.orderService.updateStatusByAdvertiserId(advertiserIdList,status);
		Boolean campaignFlag = this.campaignService.updateStatusByAdvertiserId(advertiserIdList, status);
		Boolean adGroupFlag = this.adGroupService.updateStatusByAdvertiserId(advertiserIdList, status);
		for(Long l:advertiserIdList){
			list.addAll(adGroupService.findAllAdGroudByAdvertiserId(l));
		}
		Boolean bannerFlag = false;
		if(list.size()>0){
			bannerFlag = this.bannerService.updateStatusByAdGroupId(list, status);
		}else{
			System.out.println("改投放下没有创意");
			bannerFlag = true;
		} 
		
		return advertiserFlag&&orderFlag&&campaignFlag&&adGroupFlag&&bannerFlag;
	}

}
