package com.dst.slms.plan.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.dst.slms.common.config.Constant;
import com.dst.slms.common.entity.CoreInfo;
import com.dst.slms.common.entity.sic.SelectorItemCollection;
import com.dst.slms.common.excetion.BizException;
import com.dst.slms.common.service.util.DataGrid;
import com.dst.slms.common.service.util.EntityQuery;
import com.dst.slms.common.utils.R;
import com.dst.slms.common.utils.UIRuleUtil;
import com.dst.slms.common.utils.bos.BOSUuid;
import com.dst.slms.plan.entity.AnnualPaymentPlanInfo;
import com.dst.slms.plan.entity.AnnualPlanDetailsInfo;
import com.dst.slms.plan.entity.CyclePaymentPlanE1Info;
import com.dst.slms.plan.entity.CyclePaymentPlanInfo;
import com.dst.slms.plan.entity.MonthlyPaymentPlanEInfo;
import com.dst.slms.plan.entity.MonthlyPaymentPlanInfo;
import com.dst.slms.plan.service.IMonthlyPaymentPlanService;
import com.dst.slms.system.entity.SysOrgInfo;
import com.dst.slms.system.service.ISysOrgService;

import cn.hutool.core.bean.BeanUtilTo;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.hibernate.criterion.Restrictions;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dst.slms.base.entity.MarketAccountInfo;
import com.dst.slms.common.annotation.SysPermissionName;
import org.springframework.web.bind.annotation.PostMapping;
/**   
 * @Title: 月度支付计划 Controller
 * @Description: 月度支付计划
 * @author 
 * @date 2020-05-02 16:24:33
 * @version V1.0   
 *
 */
@SuppressWarnings("unchecked")
@Controller
@RequestMapping("/monthlyPaymentPlanController")
@SysPermissionName(name="月度支付计划",type=Constant.MENU)
public class MonthlyPaymentPlanController extends AbstractMonthlyPaymentPlanController {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(MonthlyPaymentPlanController.class);
	
	@Autowired
	private IMonthlyPaymentPlanService iMonthlyPaymentPlanService;
	
	@Autowired
	private ISysOrgService iAdminService;
	
	/**
	 * 审核
	 */
	@SysPermissionName(name="审核")
	@RequiresPermissions("mon:monthlyPaymentPlan:audit")
	@ResponseBody
    @PostMapping(value = "/audit")
	public R auditAction(MonthlyPaymentPlanInfo info, HttpServletRequest req) {
		R audit = iMonthlyPaymentPlanService.audit(info.getId(),com.dst.slms.common.utils.SysContext.getUserId());
		info = iMonthlyPaymentPlanService.getEntity(MonthlyPaymentPlanInfo.class, info.getId());
		info.setIsnew(true);
		iMonthlyPaymentPlanService.save(info);
		String number = info.getNumber();
		Integer editionnumber = Integer.valueOf(info.getVersions());
		editionnumber = editionnumber-1;
		EntityQuery eq = new EntityQuery(MonthlyPaymentPlanInfo.class);
		eq.eq("number", number);
		eq.eq("versions", editionnumber+"");
		eq.add();
		List entityList = iMonthlyPaymentPlanService.getEntityList(eq);
		if(entityList.size()>0){
			MonthlyPaymentPlanInfo object = (MonthlyPaymentPlanInfo) entityList.get(0);
			String sql = "update yc_cost_monthlyPaymentPlan set fisnew = 'N' where fid = '"+object.getId()+"'";
			iMonthlyPaymentPlanService.executeSql(sql);
		}
		
		return audit;
	}
	
	/**
	 * 反审核
	 */
	@SysPermissionName(name="反审核")
	@RequiresPermissions("mon:monthlyPaymentPlan:unAudit")	 
	@ResponseBody
    @PostMapping(value = "/unAudit")
	public R unAuditAction(MonthlyPaymentPlanInfo info, HttpServletRequest req) {
		info = iMonthlyPaymentPlanService.getEntity(MonthlyPaymentPlanInfo.class, info.getId());
		String sql = "select fid from yc_cost_monthlyPaymentPlan where fstate != 'AUDIT' and fnumber ='"+info.getNumber()+"'";
		List<Map<String,Object>> executeSqlQuery = iMonthlyPaymentPlanService.executeSqlQuery(sql);
		if(executeSqlQuery.size()>0){
			throw new BizException("当前数据已有新版本，不能反审批该版本数据");
		}
		if(!info.getIsnew()){
			throw new BizException("当前数据不是最新版本，不能反审批");
		}
		
		R unAudit = iMonthlyPaymentPlanService.unAudit(info.getId());
		SelectorItemCollection sic = new SelectorItemCollection();
		sic.add("isnew");
		info.setIsnew(false);
		iMonthlyPaymentPlanService.save(info,sic);
		String number = info.getNumber();
		Integer editionnumber = Integer.valueOf(info.getVersions());
		editionnumber = editionnumber-1;
		
		EntityQuery eq = new EntityQuery(MonthlyPaymentPlanInfo.class);
		eq.eq("number", number);
		eq.eq("versions", editionnumber+"");
		eq.add();
		List entityList = iMonthlyPaymentPlanService.getEntityList(eq);
		if(entityList.size()>0){
			MonthlyPaymentPlanInfo object = (MonthlyPaymentPlanInfo) entityList.get(0);
			sql = "update yc_cost_monthlyPaymentPlan set fisnew = 'Y' where fid = '"+object.getId()+"'";
			iMonthlyPaymentPlanService.executeSql(sql);
		}
		return unAudit;
	}
	
	@Override
	public EntityQuery getQueryExecutor(HttpServletRequest request, CoreInfo info, DataGrid dataGrid) {
		String typeId = request.getParameter("typeId");
		EntityQuery queryExecutor = super.getQueryExecutor(request, info, dataGrid);
		if(UIRuleUtil.isNotNull(typeId)){
			String[] split = typeId.split(",");
			queryExecutor.in("marketProject.id", split);
		}
		queryExecutor.add();
		return queryExecutor;
	}
	
	@Override
	public Object createNewModel(HttpServletRequest req) {
		MonthlyPaymentPlanInfo createNewModel = (MonthlyPaymentPlanInfo) super.createNewModel(req);
		createNewModel.setId(BOSUuid.create("FOW6EIMC"));
		createNewModel.setIsnew(false);
		createNewModel.setVersions("1");
		 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
	     Date date = new Date();
	     createNewModel.setYear(sdf.format(date).split("-")[0]);
	     createNewModel.setMonth(Integer.valueOf(sdf.format(date).split("-")[1])+"");
		return createNewModel;
	}
	
	/**
	 * 修订
	 */
	@ResponseBody
	@RequestMapping(value="/revise")
	public ModelAndView revise(HttpServletRequest request){
		String billid = request.getParameter("billid");
		MonthlyPaymentPlanInfo maninfo = iMonthlyPaymentPlanService.getEntity(MonthlyPaymentPlanInfo.class, billid);
		MonthlyPaymentPlanInfo info = new MonthlyPaymentPlanInfo();
		BeanUtilTo.copyProperties(maninfo, info);
		info.setVersions((Integer.valueOf(maninfo.getVersions())+1)+"");
		info.setId(""); 
		info.setState("SAVE");
		info.setIsnew(false);
		for (int i = 0; i < info.getExpectedUnpaid().size(); i++) {
			info.getExpectedUnpaid().get(i).setId("");
			info.getExpectedUnpaid().get(i).setParent(null);
		}
		for (int i = 0; i < info.getMonthlyPaymentPlanE().size(); i++) {
			info.getMonthlyPaymentPlanE().get(i).setId("");
			info.getMonthlyPaymentPlanE().get(i).setParent(null);
		}
		for (int i = 0; i < info.getSigned().size(); i++) {
			info.getSigned().get(i).setId("");
			info.getSigned().get(i).setParent(null);
		}
		request.setAttribute("model", info);
		return new ModelAndView("com/dst/slms/plan/monthlypaymentplan/monthlyPaymentPlanEdit");
	}
	
	
	/**
	 * 是否最新版
	 * @param request
	 * @return
	 */
	@RequestMapping(value="/isLast")
	@ResponseBody
	public R isLast(HttpServletRequest request){
		String billid = request.getParameter("billid");//
		MonthlyPaymentPlanInfo info = iMonthlyPaymentPlanService.getEntity(MonthlyPaymentPlanInfo.class, billid);
		String sql = "select fid from yc_cost_monthlyPaymentPlan where fstate != 'AUDIT' and fnumber ='"+info.getNumber()+"'";
		String key = "true";
		List<Map<String,Object>> executeSqlQuery = iMonthlyPaymentPlanService.executeSqlQuery(sql);
		if(info.getIsnew()){
			key = "false";
			if(executeSqlQuery.size()>0){
				key = "noAudit";
			}
		}
		return R.ok("", key, "0");
	}
	
	
	/**
	 * 获取已签约数据
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@ResponseBody
	@RequestMapping(params = "getSignedByid")
	public Object getSignedByid(HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
		try {
			Object  obj = iMonthlyPaymentPlanService.getSignedByid(response,request, dataGrid);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 获取已签约数据
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@ResponseBody
	@RequestMapping(params = "getExpectedUnpaidByid")
	public Object getExpectedUnpaidByid(HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
		try {
			Object  obj = iMonthlyPaymentPlanService.getExpectedUnpaidByid(response,request, dataGrid);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 获取数据
	 * @param request
	 */
	@ResponseBody
    @RequestMapping(value = "getMonthlyPaymentPlanEByid")
	public void list(HttpServletRequest request) {
		String parentid = UIRuleUtil.getString(request.getParameter("parentid"));
		String newparentid = request.getParameter("newparentid");
		if(UIRuleUtil.isNotNull(newparentid)&&newparentid.equals("-1")){
			parentid = null;
 		}
		String year = request.getParameter("year");
		String month = request.getParameter("month");
		String marketProjectId = request.getParameter("marketProjectId");
		if(UIRuleUtil.isNotNull(parentid)){
			
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("number", "asc");
			EntityQuery eq = new EntityQuery(MarketAccountInfo.class);
			eq.eq("isEnable", true);
			eq.setOrder(map);
			eq.add();
			List<MarketAccountInfo> list  = getService().getEntityList(eq);
			
			Map<String,MonthlyPaymentPlanEInfo> e1InfoMapping = new HashMap<>();
			eq = new EntityQuery(MonthlyPaymentPlanEInfo.class);
			eq.eq("parent.id", parentid);
			eq.add();
			List<MonthlyPaymentPlanEInfo> entityList = getService().getEntityList(eq);
			entityList.forEach(per->{
				if(per.getMarketAccount()!=null){
					e1InfoMapping.put(per.getMarketAccount().getNumber(), per);
				}
			});
			
			MarketAccountInfo rootInfo = new MarketAccountInfo();
			rootInfo.setName("营销科目");
			rootInfo.setNumber("N000");
			rootInfo.setId("ROOT");
			list.add(0,rootInfo);
			
			List<Map<String,Object>> resultList = new ArrayList<>();
			list.forEach(per->{
				Map<String,Object> value = new HashMap<>();
				if(per.getParent()!=null) {
					value.put("_parentId", per.getParent().getId());
				}else if(!"N000".equals(per.getNumber())){
					value.put("_parentId", "ROOT");
				}
				value.put("id", per.getId());
				value.put("state", "open");
				value.put("icon", "");
				
				MonthlyPaymentPlanEInfo monthlyPaymentPlanEInfo = e1InfoMapping.get(per.getNumber());
				value.put("isLeaf", per.getIsLeaf());
				value.put("name", per.getName());
				value.put("number",per.getNumber());
				value.put("currentApplication", monthlyPaymentPlanEInfo!=null?monthlyPaymentPlanEInfo.getCurrentApplication():BigDecimal.ZERO); 
				value.put("oldBalance",  monthlyPaymentPlanEInfo!=null?monthlyPaymentPlanEInfo.getOldBalance():BigDecimal.ZERO);
				value.put("monthlyBalance", monthlyPaymentPlanEInfo!=null?monthlyPaymentPlanEInfo.getMonthlyBalance():BigDecimal.ZERO);
				value.put("verifyabc", monthlyPaymentPlanEInfo!=null?monthlyPaymentPlanEInfo.getVerifyabc():BigDecimal.ZERO); 
				resultList.add(value);
			});
			Map mp = new HashMap<>();
			mp.put("rows", resultList);
			mp.put("total", list.size());
			writeSuccessJson(mp);
		}else{
			if(UIRuleUtil.isNotNull(year)&&UIRuleUtil.isNotNull(month)&&UIRuleUtil.isNotNull(marketProjectId)){
				if(Integer.valueOf(month)<10){
					month="0"+month;
				}
				String monthsql=getMonthSumSql(month);
				//最新的年度支付计划截至所选年月之前的支付金额合计
				StringBuilder sql = new StringBuilder("select l1.FmarketAccounID "+monthsql+" from  yc_cost_annualPlanDetails l1 left join yc_cost_annualPaymentPlan  l2 ");
				sql.append(" on l1.FparentId=l2.fid  ");
				sql.append(" where l2.fisnew='Y'   and l2.Fyear<='"+year+"' and l2.FmarketProjectID='"+marketProjectId+"' ");
				sql.append(" GROUP BY l1.FmarketAccounID");
				List<Map<String,Object>> list = getService().executeSqlQuery(sql.toString());
				Map<String,Object> yearmap = new HashMap<String,Object>();
				if(list!=null&&list.size()>0){
					for (Map<String, Object> map : list) {
						yearmap.put(map.get("FmarketAccounID")+"", map.get("amountpaid")+"");
					}
				}
				//当前科目的付款申请单金额
				sql = new StringBuilder(" select ifnull(sum(FtaxReqAmt),0) taxReqAmt,l2.FmarkAccountID from yc_cost_paymentReq l1 ");
				sql.append(" left join yc_cost_saleContract l2 on l1.FcontractID=l2.fid ");
				sql.append(" where l1.FSTATE='AUDIT' and l1.FprojectID='"+marketProjectId+"' ");
				sql.append(" GROUP BY l2.FmarkAccountID ");
				list = getService().executeSqlQuery(sql.toString());
				Map<String,Object> taxReqAmtmap = new HashMap<String,Object>();
				if(list!=null&&list.size()>0){
					for (Map<String, Object> map : list) {
						taxReqAmtmap.put(map.get("FmarkAccountID")+"", map.get("taxReqAmt")+"");
					}
				}
				//当月预算
				sql = new StringBuilder(" select l1.FmarketAccounID "+getMonthSum(month)+"   from  yc_cost_annualPlanDetails l1 left join yc_cost_annualPaymentPlan  l2  ");
				sql.append(" on l1.FparentId=l2.fid  ");
				sql.append(" where l2.fisnew='Y'  and l2.Fyear='"+year+"' and l2.FmarketProjectID='"+marketProjectId+"' ");
				sql.append(" GROUP BY l1.FmarketAccounID");
				list = getService().executeSqlQuery(sql.toString());
				Map<String,Object> monthmap = new HashMap<String,Object>();
				if(list!=null&&list.size()>0){
					for (Map<String, Object> map : list) {
						monthmap.put(map.get("FmarketAccounID")+"", map.get("amountpaid")+"");
					}
				}
				//本期申请
				sql = new StringBuilder(" select ifnull(sum(l1.FpayAmt),0) payAmt,l2.FmarkAccountID from yc_cost_saleConEconomics  l1 ");
				sql.append(" left join yc_cost_saleContract l2 on l1.FparentId =l2.fid  ");
				sql.append(" where date_format(l1.FbizDate,'%Y%m') = '"+year+month+"' and l2.FprojectID='"+marketProjectId+"' ");
				sql.append(" GROUP BY l2.FmarkAccountID  ");
				list = getService().executeSqlQuery(sql.toString());
				Map<String,Object> payAmtmap = new HashMap<String,Object>();
				if(list!=null&&list.size()>0){
					for (Map<String, Object> map : list) {
						payAmtmap.put(map.get("FmarkAccountID")+"", map.get("payAmt")+"");
					}
				}
				
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("number", "asc");
				EntityQuery eq = new EntityQuery(MarketAccountInfo.class);
				eq.eq("isEnable", true);
				eq.setOrder(map);
				eq.add();
				List<MarketAccountInfo> marketlist  = getService().getEntityList(eq);
				MarketAccountInfo rootInfo = new MarketAccountInfo();
				rootInfo.setName("营销科目");
				rootInfo.setNumber("N000");
				rootInfo.setId("ROOT");
				marketlist.add(0,rootInfo);
				
				List<Map<String,Object>> resultList = new ArrayList<>();
				marketlist.forEach(per->{
					Map<String,Object> value = new HashMap<>();
					if(per.getParent()!=null) {
						value.put("_parentId", per.getParent().getId());
					}else if(!"N000".equals(per.getNumber())){
						value.put("_parentId", "ROOT");
					}
					value.put("id", per.getId());
					value.put("state", "open");
					value.put("icon", "");
					value.put("isLeaf", per.getIsLeaf());
					value.put("name", per.getName());
					value.put("number",per.getNumber());
					value.put("currentApplication", payAmtmap.get(per.getId())!=null?new BigDecimal(payAmtmap.get(per.getId())+""):BigDecimal.ZERO); 
					BigDecimal a  = yearmap.get(per.getId())!=null?new BigDecimal(yearmap.get(per.getId())+""):BigDecimal.ZERO;
					BigDecimal b  = taxReqAmtmap.get(per.getId())!=null?new BigDecimal(taxReqAmtmap.get(per.getId())+""):BigDecimal.ZERO;
					value.put("oldBalance", a.add(new BigDecimal("-"+b)));
					value.put("monthlyBalance", monthmap.get(per.getId())!=null?new BigDecimal(monthmap.get(per.getId())+""):BigDecimal.ZERO);
					resultList.add(value);
				});
				Map mp = new HashMap<>();
				mp.put("rows", resultList);
				mp.put("total", list.size());
				writeSuccessJson(mp);
			}
		}
	}

	private String getMonthSumSql(String month) {
		String [] months=new String[]{"sum(l1.Fjan)","sum(l1.Ffeb)","sum(l1.Fmar)","sum(l1.Fapr)","sum(l1.Fmay)","sum(l1.Fjun)","sum(l1.Fjul)","sum(l1.Faug)","sum(l1.Fsep)","sum(l1.Foct)","sum(l1.Fnov)","sum(l1.Fdec)"};
		StringBuilder sql = new StringBuilder();
		for (int i = 0; i < Integer.valueOf(month)-1; i++) {
			if(sql.length()>0){
				sql.append("+"+months[i]);
			}else{
				sql.append(","+months[i]);
			}
		}
		sql.append(" amountpaid ");
		return sql.toString();
	}
	private String getMonthSum(String month) {
		String [] months=new String[]{",sum(l1.Fjan)",",sum(l1.Ffeb)",",sum(l1.Fmar)",",sum(l1.Fapr)",",sum(l1.Fmay)",",sum(l1.Fjun)",",sum(l1.Fjul)",",sum(l1.Faug)",",sum(l1.Fsep)",",sum(l1.Foct)",",sum(l1.Fnov)",",sum(l1.Fdec)"};
		return months[Integer.valueOf(month)-1]+" amountpaid";
	}
	
	@Override
	public void verifyInput(CoreInfo info, HttpServletRequest req) {
		super.verifyInput(info, req);
		MonthlyPaymentPlanInfo baseInfo = (MonthlyPaymentPlanInfo)info;
		String parameter = req.getParameter("editTreeGrid_JSON");
		try {
			String json = URLDecoder.decode(parameter,"utf-8");
			JSONArray arrayList = JSON.parseArray(json);
			for(Object obj:arrayList){
				JSONObject eObj = (JSONObject)obj;
				if(eObj.get("children") != null && eObj.get("children") instanceof JSONArray){
					JSONArray children = (JSONArray)eObj.get("children");
					for (int i = 0; i < children.size(); i++) {
						JSONObject tempObj = (JSONObject) children.get(i);
						
						if(tempObj.get("children") != null && tempObj.get("children") instanceof JSONArray){
							JSONArray children1 = (JSONArray)tempObj.get("children");
							for (int j = 0; j < children1.size(); j++) {
								baseInfo.getMonthlyPaymentPlanE().add(getCastJsonTOEntity((JSONObject) children1.get(j)));
							}
						}
						baseInfo.getMonthlyPaymentPlanE().add(getCastJsonTOEntity(tempObj));
					}
				}
				baseInfo.getMonthlyPaymentPlanE().add(getCastJsonTOEntity(eObj));
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		System.out.println();
	}
	
	private MonthlyPaymentPlanEInfo getCastJsonTOEntity(JSONObject eObj){
		MonthlyPaymentPlanEInfo e1Info = new MonthlyPaymentPlanEInfo();
		e1Info.setMarketAccountName(UIRuleUtil.getString(eObj.get("name")));
		MarketAccountInfo accountInfo = new MarketAccountInfo();
		accountInfo.setId(UIRuleUtil.getString(eObj.get("id")));
		e1Info.setMarketAccount(accountInfo);
		e1Info.setCurrentApplication(UIRuleUtil.getBigDecimal(eObj.get("currentApplication")));
		e1Info.setOldBalance(UIRuleUtil.getBigDecimal(eObj.get("oldBalance")));
		e1Info.setMonthlyBalance(UIRuleUtil.getBigDecimal(eObj.get("monthlyBalance")));
		e1Info.setVerifyabc(UIRuleUtil.getBigDecimal(eObj.get("verifyabc")));
		return e1Info;
	}

}
