package com.goafanti.common.task;


import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.mail.MessagingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.goafanti.common.bo.EmailBo;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.NoticeMapper;
import com.goafanti.common.dao.PaymentNodeMapper;
import com.goafanti.common.dao.TArrearsDunMapper;
import com.goafanti.common.dao.TOrderMidMapper;
import com.goafanti.common.dao.TOrderNewMapper;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.model.Notice;
import com.goafanti.common.model.PaymentNode;
import com.goafanti.common.model.TArrearsDun;
import com.goafanti.common.model.TOrderDun;
import com.goafanti.common.model.TOrderMid;
import com.goafanti.common.model.TOrderNew;
import com.goafanti.common.utils.LoggerUtils;
import com.goafanti.common.utils.SendEmailUtil;
import com.goafanti.order.bo.InputNewOrderDunBo;
import com.goafanti.order.bo.OrderDunTaskBo;
import com.goafanti.order.bo.OutNewOrderDunBo;
import com.goafanti.order.bo.TOrderNewBo;
import com.goafanti.order.enums.OrderDunProjectType;
import com.goafanti.order.service.NewOrderDunService;
import com.goafanti.order.service.OrderNewService;
import com.goafanti.order.service.OrderProjectService;
import com.goafanti.organization.bo.OutPaymentNode;

@Component
@Controller
public class OrderDunTask {
	@Autowired
	private OrderNewService orderNewService;
	@Autowired
	private NewOrderDunService  newOrderDunService;
	@Autowired
	private TOrderNewMapper	tOrderNewMapper;
	@Autowired
	private TArrearsDunMapper	tArrearsDunMapper;
	@Autowired
	private TOrderMidMapper	tOrderMidMapper;
	@Autowired
	private NoticeMapper	noticeMapper;
	@Autowired
	private PaymentNodeMapper	paymentNodeMapper;
	@Autowired
	private OrderProjectService	orderProjectService;
	Logger							logger	= LoggerFactory.getLogger(OrderDunTask.class);
	
	/**
	 * 	每天凌晨3点轮
	 * @throws InterruptedException
	 */
	@ResponseBody
	@Scheduled(cron = "0 0 3  * * ?")
	@Transactional(rollbackFor=Exception.class)
	public void startTask() throws InterruptedException {
		updateNewOrderDun();
		Thread.sleep(2000);
		updateorderDun();
	}
	
	/**
	 * 询处理需要新催款的信息
	 */
	@RequestMapping(value = "/open/updateNewOrderDun", method = RequestMethod.GET)
	public void updateNewOrderDun(){
  		try {
  			LoggerUtils.debug(logger, "======================新催款任务轮询启动===================");
  		
  		List<OutNewOrderDunBo> list= newOrderDunService.selectAllOrderDun();
  		Calendar calendar=Calendar.getInstance();   
  		Calendar calendar2=Calendar.getInstance();
  		Date date =new Date();
  		for (OutNewOrderDunBo o : list) {
  			calendar.setTime(date);
  			calendar2.setTime(o.getCreateTime());
  			if (o!=null&&o.getApproval()!=null&&o.getApproval()!=0&&o.getDunType()==1&&o.getWaitDay()!=null) {
  					calendar2.add(Calendar.DATE, o.getWaitDay());
  					if (calendar.getTimeInMillis() > calendar2.getTimeInMillis()) {//当前时间大于计算后时间则触发
  						updateOrderDun(o);
  						Thread.sleep(2000);
  					}
			}
  			if(o.getProjectType()==OrderDunProjectType.HY.getCode()&&o.getDunType()==2) {
  				calendar2.add(Calendar.DATE, o.getEffectiveCount()*180);
  				CalendarTimeCleared(calendar2);
  				if (calendar.getTimeInMillis() > calendar2.getTimeInMillis()) {//当前时间大于计算后时间则触发
  	  	  			updateOrderDun(o);
  	  	  			Thread.sleep(2000);
  				}
  			}
  			if(o.getProjectType()==OrderDunProjectType.CS.getCode()&&o.getDunType()==2) {
  			//获取年
  				int year = calendar2.get(Calendar.YEAR);  
  		        //获取月份，0表示1月份
  		        int month = calendar2.get(Calendar.MONTH) + 1;
  		        if(month<10)year=year+1;
  		        if(month>9)year=year+2;
  		        calendar2.set(year, 5, 1);
  		        CalendarTimeCleared(calendar2);
  				if (calendar.getTimeInMillis() > calendar2.getTimeInMillis()) {//当前时间大于计算后时间则触发
  	  	  			updateOrderDun(o);
  	  	  			Thread.sleep(2000);
  				}
  			}
  	  		if (o.getDunType()==0) {
  	  		calendar2.setTime(o.getCustomizeTime());
  	  		CalendarTimeCleared(calendar);
  	  			if (calendar.equals(calendar2)) {
  	  				updateOrderDun(o);
	  	  			Thread.sleep(2000);
				}
				
			}
		}
  		LoggerUtils.debug(logger, "======================催款任务结束,付款催款开始===================");
  		List<OutPaymentNode> list2=paymentNodeMapper.selectByStatus(0);
  		for (OutPaymentNode pn : list2) {
  			calendar2.setTime(pn.getCreateTime());
  			if(pn.getProjectType()==OrderDunProjectType.HY.getCode()&&pn.getDunType()==2) {
  				calendar2.add(Calendar.DATE, pn.getEffectiveCount()*180);
  				CalendarTimeCleared(calendar2);
  				if (calendar.getTimeInMillis() > calendar2.getTimeInMillis()) {//当前时间大于计算后时间则触发
  					updatePaymentNode(pn);
  	  	  			Thread.sleep(2000);
  				}
  			}
  			if(pn.getProjectType()==OrderDunProjectType.CS.getCode()&&pn.getDunType()==2) {
  				//	获取年
  				int year = calendar2.get(Calendar.YEAR);  
  		        //获取月份，0表示1月份
  		        int month = calendar2.get(Calendar.MONTH) + 1;
  		        if(month<10)year=year+1;
  		        if(month>9)year=year+2;
  		        calendar2.set(year, 5, 1);
  		        CalendarTimeCleared(calendar2);
  				if (calendar.getTimeInMillis() > calendar2.getTimeInMillis()) {//当前时间大于计算后时间则触发
  					updatePaymentNode(pn);
  	  	  			Thread.sleep(2000);
  				}
  			}
  	  		if (pn.getDunType()==0) {
  	  		calendar2.setTime(pn.getPartyTime());
  	  		CalendarTimeCleared(calendar);
  	  			if (calendar.equals(calendar2)) {
  	  				updatePaymentNode(pn);
	  	  			Thread.sleep(2000);
				}
				
			}
		}
  		} catch (Exception e) {
  			EmailBo emailBo = new EmailBo( "催款处理失败",  AFTConstants.ADMIN_EMAIL,  "超管", "平台",  "系统", "催款处理失败");
			try {
				SendEmailUtil.getInstance().send(emailBo);
			} catch (UnsupportedEncodingException | MessagingException e1) {
				e1.printStackTrace();
			}
  			LoggerUtils.error(getClass(), "=============================================");
			LoggerUtils.error(getClass(), "新催款的信息处理失败", e);
			LoggerUtils.error(getClass(), "=============================================");
		}
  	
  		//处理旧催款
  		updateorderDun();
  		
  	}
	
	
	private void updatePaymentNode(OutPaymentNode pn) {
		PaymentNode p=new PaymentNode();
		p.setId(pn.getId());
		p.setDunStatus(1);
		p.setStartTime(new Date());
		paymentNodeMapper.updateByPrimaryKeySelective(p);
		orderProjectService.addNoticAndEmail(pn,NoticeStatus.PAYMENT_DUN.getCode());
	}
	
	


	private void CalendarTimeCleared(Calendar calendar) {
		calendar.set(Calendar.HOUR_OF_DAY, 0);
	    calendar.set(Calendar.MINUTE, 0);
	    calendar.set(Calendar.SECOND, 0);
	    calendar.set(Calendar.MILLISECOND, 0);
	}


	private void updateOrderDun(OutNewOrderDunBo t) throws UnsupportedEncodingException, MessagingException {
		InputNewOrderDunBo o=new InputNewOrderDunBo();
		o.setId(t.getId());
		o.setStatus(1);
		o.setStartTime(new Date());
		newOrderDunService.updateDun(o);
		tOrderMidMapper.addOrderReceivables(t.getOrderNo(),t.getMoney());
		TOrderMid tm=tOrderMidMapper.selectByOrderNo(t.getOrderNo());
			TArrearsDun td=new TArrearsDun();
			td.setOrderArrears(tm.getOrderArrears());
			td.setOrderReceivables(tm.getOrderReceivables());
			if (tArrearsDunMapper.checkOrderNo(t.getOrderNo(),null)<1) {
				td.setOrderNo(t.getOrderNo());
				tArrearsDunMapper.insertSelective(td);
			}else if(tArrearsDunMapper.checkOrderNo(t.getOrderNo(),0)>0){
				Integer i=tArrearsDunMapper.selectByStatus(t.getOrderNo(), 0);
				td.setId(i);
				tArrearsDunMapper.updateByPrimaryKeySelective(td);
			}
		TOrderNew t2=tOrderNewMapper.selectByPrimaryKey(t.getOrderNo());
		orderNewService.addTimingTaskNewDunNoticAndSendEmail(t2, t);
	}
	
	/**
	* 	每月1号凌晨4点轮询处理需要欠款催款的信息
	*
	*/
	@Scheduled(cron = "0 0 4 1 * ?") 
	@RequestMapping(value = "/open/pushOrderArrearsDun", method = RequestMethod.GET)
	public void pushOrderArrearsDun(){
		try {
			LoggerUtils.debug(logger, "======================欠款催款启动===================");
			Date date=new Date();
			//运算 list(未启动) list2(催款中) list3(已完成)订单的欠款催款
			List<TArrearsDun> list=tArrearsDunMapper.selectStatusAll(0);
			List<TArrearsDun> list2=tArrearsDunMapper.selectStatusAll(1);
			List<TArrearsDun> list3=tArrearsDunMapper.selectStatusAndAmount(2);
			for (TArrearsDun td : list) {
				TOrderMid tm=tOrderMidMapper.selectByOrderNo(td.getOrderNo());
				//如果欠款大于0则需要触发邮件
				if (tm.getOrderArrears().compareTo(new BigDecimal(0))>0) {
					td.setDunStatus(1);
					td.setStartTime(date);
					td.setOrderArrears(tm.getOrderArrears());
					td.setOrderReceivables(tm.getOrderReceivables());
					addNoticAndSendEmail(td.getOrderNo(),td,NoticeStatus.ORDER_ARREARS_DUN.getCode());
					tArrearsDunMapper.updateByPrimaryKeySelective(td);
				}else if(tm.getOrderArrears().compareTo(new BigDecimal(0))<1) {
					td.setDunStatus(2);
					td.setEndTime(date);
					td.setOrderArrears(tm.getOrderArrears());
					tArrearsDunMapper.updateByPrimaryKeySelective(td);
				}
				Thread.sleep(2000);
			}
			for (TArrearsDun ta : list2) {
				TOrderMid tm=tOrderMidMapper.selectByOrderNo(ta.getOrderNo());
				//如果欠款大于0则需要触发邮件
				if (tm.getOrderArrears().compareTo(new BigDecimal(0))>0) {
					ta.setDunStatus(3);
					tArrearsDunMapper.updateByPrimaryKeySelective(ta);
					ta.setId(null);
					ta.setDunStatus(1);
					ta.setStartTime(date);
					ta.setOrderArrears(tm.getOrderArrears());
					ta.setOrderReceivables(tm.getOrderReceivables());
					tArrearsDunMapper.insertSelective(ta);
					addNoticAndSendEmail(ta.getOrderNo(),ta,NoticeStatus.ORDER_ARREARS_DUN.getCode());
				}else if(tm.getOrderArrears().compareTo(new BigDecimal(0))<1) {
					ta.setDunStatus(2);
					ta.setOrderArrears(tm.getOrderArrears());
					tArrearsDunMapper.updateByPrimaryKeySelective(ta);
				}
				Thread.sleep(2000);
			
			}
			for (TArrearsDun ta : list3) {
				TOrderMid tm=tOrderMidMapper.selectByOrderNo(ta.getOrderNo());
				//如果欠款大于0则需要触发邮件
				if (tm.getOrderArrears().compareTo(new BigDecimal(0))>0) {
					ta.setDunStatus(3);
					tArrearsDunMapper.updateByPrimaryKeySelective(ta);
					ta.setId(null);
					ta.setDunStatus(1);
					ta.setStartTime(date);
					ta.setOrderArrears(tm.getOrderArrears());
					ta.setOrderReceivables(tm.getOrderReceivables());
					tArrearsDunMapper.insertSelective(ta);
					addNoticAndSendEmail(ta.getOrderNo(),ta,NoticeStatus.ORDER_ARREARS_DUN.getCode());
				}else if(tm.getOrderArrears().compareTo(new BigDecimal(0))<1) {
					ta.setDunStatus(2);
					ta.setOrderReceivables(tm.getOrderReceivables());
					ta.setOrderArrears(tm.getOrderArrears());
					tArrearsDunMapper.updateByPrimaryKeySelective(ta);
				}
				Thread.sleep(2000);
			
			}
		} catch (Exception e) {
			LoggerUtils.error(getClass(), "===========================欠款催款失败==========================", e);
		}
	}
	
	
	private void addNoticAndSendEmail(String orderNo, TArrearsDun td, Integer code) throws UnsupportedEncodingException, MessagingException {
		TOrderNewBo b  = tOrderNewMapper.getSaleIdByOno(orderNo);
			String str=NoticeStatus.getValueByCode(code)+": 订单编号 -"+orderNo+"， 操作人: 平台超管中心 - yxy。";
			Notice n =new Notice();
			n.setId(UUID.randomUUID().toString());
			n.setAid(b.getSalesmanId());
			n.setNoticeType(code);
			n.setContent(str);
			n.setReaded(0);//未读
			noticeMapper.insertSelective(n);
	}


	/**
	*
	*
	*/
//	@RequestMapping(value = "/open/updateOrderDun", method = RequestMethod.GET)
//	@Scheduled(cron = "0 0 2  * * ?") 
  	@Transactional(rollbackFor=Exception.class)
	public void updateorderDun(){
  		try {
  			LoggerUtils.debug(logger, "======================催款任务轮询启动===================");
  		List<OrderDunTaskBo> list=orderNewService.selectAllOrderDun();
  		for (OrderDunTaskBo t : list) {
			if (t.getDunSubject()/10==1) {//1则为订单催款信息否则为项目催款信息
				if (t.getDunSubject()%10==t.getOrderStatus()&&t.getSettlementAmount().compareTo(t.getMoney()) == -1) {
					 updateOrderDun(t);
						Thread.sleep(2000);
				}
			}else {
				if (t.getDunSubject()%10>=t.getProjectStatus()&&t.getSettlementAmount().compareTo(t.getMoney()) == -1) {
					 updateOrderDun(t);
					 Thread.sleep(2000);
				}
			}
		}
  		} catch (Exception e) {
  			LoggerUtils.error(getClass(), "=============================================");
			LoggerUtils.error(getClass(), "催款的信息处理失败", e);
			LoggerUtils.error(getClass(), "=============================================");
		}
  		
  	}


	private void updateOrderDun(OrderDunTaskBo t) throws UnsupportedEncodingException, MessagingException {
		LoggerUtils.debug(logger, "======================修改催款任务===================");
		TOrderDun tDun=new TOrderDun();
		 tDun.setId(t.getId());
		 tDun.setDunStatus(1);
		 tDun.setStartTime(new Date());
		 orderNewService.updateOrderDun(tDun);
		orderNewService.addNoticAndSendEmail(t.getOrderNo(),t,NoticeStatus.ORDER_DUN.getCode());
	}
  
}
