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.CyclePaymentPlanE1Info;
import com.dst.slms.plan.entity.CyclePaymentPlanInfo;
import com.dst.slms.plan.service.ICyclePaymentPlanService;
import com.dst.slms.system.entity.SysOrgInfo;
import cn.hutool.core.bean.BeanUtilTo;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
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.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.apache.shiro.authz.annotation.RequiresPermissions;

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.base.entity.MarketProjectInfo;
import com.dst.slms.base.entity.SysYearInfo;
import com.dst.slms.common.annotation.SysPermissionName;
import org.springframework.web.bind.annotation.PostMapping;
/**   
 * @Title: 项目全周期费用规划 Controller
 * @Description: 项目全周期费用规划
 * @author 
 * @date 2020-05-02 11:14:38
 * @version V1.0   
 *
 */
@SuppressWarnings("unchecked")
@Controller
@RequestMapping("/cyclePaymentPlanController")
@SysPermissionName(name="项目全周期费用规划",type=Constant.MENU)
public class CyclePaymentPlanController extends AbstractCyclePaymentPlanController {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(CyclePaymentPlanController.class);
	
	@Autowired
	private ICyclePaymentPlanService iCyclePaymentPlanService;
	
	/**
	 * 审核
	 */
	@SysPermissionName(name="审核")
	@RequiresPermissions("Cyn:CyclePaymentPlan:audit")
	@ResponseBody
    @PostMapping(value = "/audit")
	public R auditAction(CyclePaymentPlanInfo info, HttpServletRequest req) {
		R audit = iCyclePaymentPlanService.audit(info.getId(),com.dst.slms.common.utils.SysContext.getUserId());
		
		info = iCyclePaymentPlanService.getEntity(CyclePaymentPlanInfo.class, info.getId());
		info.setIsnew(true);
		iCyclePaymentPlanService.save(info);
		String number = info.getNumber();
		Integer editionnumber = info.getEditionnumber();
		editionnumber = editionnumber-1;
		EntityQuery eq = new EntityQuery(CyclePaymentPlanInfo.class);
		eq.eq("number", number);
		eq.eq("editionnumber", editionnumber);
		eq.add();
		List entityList = iCyclePaymentPlanService.getEntityList(eq);
		if(entityList.size()>0){
			CyclePaymentPlanInfo object = (CyclePaymentPlanInfo) entityList.get(0);
			String sql = "update yc_cost_CyclePaymentPlan set fisnew = 'N' where fid = '"+object.getId()+"'";
			iCyclePaymentPlanService.executeSql(sql);
		}
		
		return audit;
	}
	
	/**
	 * 获取数据
	 * @param request
	 */
	@ResponseBody
    @RequestMapping(value = "getAccountEntryData")
	public void list(HttpServletRequest request) {
		String id = UIRuleUtil.getString(request.getParameter("id"));
		String oldId = UIRuleUtil.getString(request.getParameter("oldId"));
		if(UIRuleUtil.isNull(id)){
			id = oldId;
		}
		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,CyclePaymentPlanE1Info> e1InfoMapping = new HashMap<>();
		eq = new EntityQuery(CyclePaymentPlanE1Info.class);
		eq.eq("parent.id", id);
		eq.add();
		List<CyclePaymentPlanE1Info> entityList = getService().getEntityList(eq);
		entityList.forEach(per->{
			if(per.getMarketAccount()!=null){
				e1InfoMapping.put(per.getMarketAccount().getNumber(), per);
			}
		});
		
		CyclePaymentPlanInfo info = iCyclePaymentPlanService.getEntity(CyclePaymentPlanInfo.class, id);
		//已发生
		Map<String,BigDecimal> yfsAmountMap = new HashMap<String,BigDecimal>();
		//已支付
		Map<String,BigDecimal> payAmountMap = new HashMap<String,BigDecimal>();
		if(info!=null && info.getProject()!=null){
			MarketProjectInfo project = info.getProject();
			String yfsAmountsql = "select FmarkAccountID,sum(FtaxConAmt) amt from yc_cost_saleContract where fstate = 'AUDIT' and FprojectID='"+project.getId()+"' group by FmarkAccountID";
			StringBuffer payAmountsql = new StringBuffer();
			payAmountsql.append(" select b.FmarkAccountID,sum(a.FtaxReqAmt) reqAmt from yc_cost_paymentReq a ");
			payAmountsql.append(" left join yc_cost_saleContract b on a.FcontractID = b.fid ");
			payAmountsql.append(" where a.fstate = 'AUDIT' and b.FprojectID='"+project.getId()+"'  ");
			payAmountsql.append(" group by b.FmarkAccountID ");
			
			List<Map<String, Object>> yfsAmountList = iCyclePaymentPlanService.executeSqlQuery(yfsAmountsql);
			for (int i = 0; i < yfsAmountList.size(); i++) {
				Map<String, Object> sqlMap = yfsAmountList.get(i);
				String FmarkAccountID = UIRuleUtil.getString(sqlMap.get("FmarkAccountID"));
				BigDecimal amt = UIRuleUtil.getBigDecimal(sqlMap.get("amt"));
				yfsAmountMap.put(FmarkAccountID, amt);
			}
			List<Map<String, Object>> payAmountList = iCyclePaymentPlanService.executeSqlQuery(payAmountsql.toString());
			for (int i = 0; i < payAmountList.size(); i++) {
				Map<String, Object> sqlMap = payAmountList.get(i);
				String FmarkAccountID = UIRuleUtil.getString(sqlMap.get("FmarkAccountID"));
				BigDecimal reqAmt = UIRuleUtil.getBigDecimal(sqlMap.get("reqAmt"));
				payAmountMap.put(FmarkAccountID, reqAmt);
			}
		}
		
		
		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", "");
			
			CyclePaymentPlanE1Info cyclePaymentPlanE1Info = e1InfoMapping.get(per.getNumber());
			
			value.put("isLeaf", per.getIsLeaf());
			value.put("name", per.getName());
			value.put("number",per.getNumber());
			value.put("planAmount", cyclePaymentPlanE1Info!=null?cyclePaymentPlanE1Info.getPlanAmount():BigDecimal.ZERO); //规划金额
			value.put("rate",  cyclePaymentPlanE1Info!=null?cyclePaymentPlanE1Info.getRate():BigDecimal.ZERO); //占比
			value.put("yfsAmount", yfsAmountMap.get(per.getId())!=null?yfsAmountMap.get(per.getId()):BigDecimal.ZERO); //已发生金额
			value.put("planYe", cyclePaymentPlanE1Info!=null?cyclePaymentPlanE1Info.getPlanYe():BigDecimal.ZERO); //规划余额
			value.put("payAmount", payAmountMap.get(per.getId())!=null?payAmountMap.get(per.getId()):BigDecimal.ZERO); //已支付
			value.put("remarks", cyclePaymentPlanE1Info!=null?cyclePaymentPlanE1Info.getRemarks():null); //说明
			resultList.add(value);
		});
		Map mp = new HashMap<>();
		mp.put("rows", resultList);
		mp.put("total", list.size());
		writeSuccessJson(mp);
	}
	
	
	/**
	 * 反审核
	 */
	@SysPermissionName(name="反审核")
	@RequiresPermissions("Cyn:CyclePaymentPlan:unAudit")	 
	@ResponseBody
    @PostMapping(value = "/unAudit")
	public R unAuditAction(CyclePaymentPlanInfo info, HttpServletRequest req) {
		info = iCyclePaymentPlanService.getEntity(CyclePaymentPlanInfo.class, info.getId());
		String sql = "select fid from yc_cost_CyclePaymentPlan where fstate != 'AUDIT' and fnumber ='"+info.getNumber()+"'";
		List<Map<String,Object>> executeSqlQuery = iCyclePaymentPlanService.executeSqlQuery(sql);
		if(executeSqlQuery.size()>0){
			throw new BizException("当前数据已有新版本，不能反审批该版本数据");
		}
		if(!info.getIsnew()){
			throw new BizException("当前数据不是最新版本，不能反审批");
		}
		
		R unAudit = iCyclePaymentPlanService.unAudit(info.getId());
		SelectorItemCollection sic = new SelectorItemCollection();
		sic.add("isnew");
		info.setIsnew(false);
		iCyclePaymentPlanService.save(info,sic);
		String number = info.getNumber();
		Integer editionnumber = info.getEditionnumber();
		editionnumber = editionnumber-1;
		
		EntityQuery eq = new EntityQuery(CyclePaymentPlanInfo.class);
		eq.eq("number", number);
		eq.eq("editionnumber", editionnumber);
		eq.add();
		List entityList = iCyclePaymentPlanService.getEntityList(eq);
		if(entityList.size()>0){
			CyclePaymentPlanInfo object = (CyclePaymentPlanInfo) entityList.get(0);
			sql = "update yc_cost_CyclePaymentPlan set fisnew = 'Y' where fid = '"+object.getId()+"'";
			iCyclePaymentPlanService.executeSql(sql);
		}
		return unAudit;
	}
	
	@Override
	public Object createNewModel(HttpServletRequest req) {
		CyclePaymentPlanInfo createNewModel = (CyclePaymentPlanInfo) super.createNewModel(req);
		createNewModel.setId(BOSUuid.create("9EXIPM7C"));
		createNewModel.setIsnew(false);
		createNewModel.setEditionnumber(1);
		
		EntityQuery eq = new EntityQuery(MarketAccountInfo.class);
		eq.eq("isEnable", true);
		eq.add();
		List entityList = iCyclePaymentPlanService.getEntityList(eq);
		for (int i = 0; i < entityList.size(); i++) {
			MarketAccountInfo account = (MarketAccountInfo) entityList.get(i);
			CyclePaymentPlanE1Info e1Info = new CyclePaymentPlanE1Info();
			e1Info.setMarketAccount(account);
			e1Info.setAccountNumber(account.getNumber());
			createNewModel.getCyclePaymentPlanE1().add(e1Info);
		}
		
		return createNewModel;
	}
	
	@Override
	public EntityQuery getQueryExecutor(HttpServletRequest request, CoreInfo info, DataGrid dataGrid) {
		EntityQuery queryExecutor = super.getQueryExecutor(request, info, dataGrid);
		//选中左边树节点ID
		String selectTreeId = request.getParameter("selectTreeId");
		 
		if(UIRuleUtil.isNotNull(selectTreeId)){
			String[] split = selectTreeId.split(",");
			queryExecutor.in("project.id", split);
		}
		queryExecutor.add();
		return queryExecutor;
	}
	
	/**
	 * 修订
	 */
	@ResponseBody
	@RequestMapping(value="/revise")
	public ModelAndView revise(HttpServletRequest request){
		String billid = request.getParameter("id");
		CyclePaymentPlanInfo maninfo = iCyclePaymentPlanService.getEntity(CyclePaymentPlanInfo.class, billid);
		
		CyclePaymentPlanInfo info = new CyclePaymentPlanInfo();
		BeanUtilTo.copyProperties(maninfo, info);
		info.setEditionnumber(maninfo.getEditionnumber()+1);
		info.setId(""); 
		info.setState("SAVE");
		info.setIsnew(false);
		for (int i = 0; i < info.getCyclePaymentPlanE1().size(); i++) {
			info.getCyclePaymentPlanE1().get(i).setId("");
			info.getCyclePaymentPlanE1().get(i).setParent(null);
		}
		for (int i = 0; i < info.getCyclePaymentPlanE2().size(); i++) {
			info.getCyclePaymentPlanE2().get(i).setId("");
			info.getCyclePaymentPlanE2().get(i).setParent(null);
		}
		request.setAttribute("model", info);
		request.setAttribute("oldId", billid);
		return new ModelAndView("com/dst/slms/plan/cyclepaymentplan/cyclePaymentPlanEdit");
	}
	
	/**
	 * 是否最新版
	 * @param request
	 * @return
	 */
	@RequestMapping(value="/isLast")
	@ResponseBody
	public R isLast(HttpServletRequest request){
		String billid = request.getParameter("billid");//
		CyclePaymentPlanInfo info = iCyclePaymentPlanService.getEntity(CyclePaymentPlanInfo.class, billid);
		String sql = "select fid from yc_cost_CyclePaymentPlan where fstate != 'AUDIT' and fnumber ='"+info.getNumber()+"'";
		String key = "true";
		List<Map<String,Object>> executeSqlQuery = iCyclePaymentPlanService.executeSqlQuery(sql);
		if(info.getIsnew()){
			key = "false";
			if(executeSqlQuery.size()>0){
				key = "noAudit";
			}
		}
		return R.ok("", key, "0");
	}
	
	@Override
	public void verifyInput(CoreInfo info, HttpServletRequest req) {
		super.verifyInput(info, req);
		CyclePaymentPlanInfo baseInfo = (CyclePaymentPlanInfo)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.getCyclePaymentPlanE1().add(getCastJsonTOEntity((JSONObject) children1.get(j)));
							}
						}
						baseInfo.getCyclePaymentPlanE1().add(getCastJsonTOEntity(tempObj));
					}
				}
				baseInfo.getCyclePaymentPlanE1().add(getCastJsonTOEntity(eObj));
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}
	
	private CyclePaymentPlanE1Info getCastJsonTOEntity(JSONObject eObj){
		CyclePaymentPlanE1Info e1Info = new CyclePaymentPlanE1Info();
		e1Info.setAccountNumber(UIRuleUtil.getString(eObj.get("name")));
		MarketAccountInfo accountInfo = new MarketAccountInfo();
		accountInfo.setId(UIRuleUtil.getString(eObj.get("id")));
		e1Info.setMarketAccount(accountInfo);
		e1Info.setYfsAmount(UIRuleUtil.getBigDecimal(eObj.get("yfsAmount")));
		e1Info.setPlanYe(UIRuleUtil.getBigDecimal(eObj.get("planYe")));
		e1Info.setPayAmount(UIRuleUtil.getBigDecimal(eObj.get("payAmount")));
		e1Info.setPlanAmount(UIRuleUtil.getBigDecimal(eObj.get("planAmount")));
		e1Info.setRemarks(UIRuleUtil.getString(eObj.get("remarks")));
		e1Info.setRate(UIRuleUtil.getBigDecimal(eObj.get("rate")));
		return e1Info;
	}
	
	
	/**
	 * 根据年份获取已发生金额和支付金额
	 */
	@ResponseBody
	@RequestMapping(value="/getAmt")
	public JSONObject getAmt(HttpServletRequest request){
		String yearId = request.getParameter("year");
		
		String projectid = request.getParameter("projectid");
		JSONObject json = new JSONObject();
		
		if(UIRuleUtil.isNotNull(yearId)&& UIRuleUtil.isNotNull(projectid)){
			SysYearInfo entity = iCyclePaymentPlanService.getEntity(SysYearInfo.class, yearId);
			String year = entity.getNumber();
			String yfsAmountsql = "select sum(FtaxConAmt) amt from yc_cost_saleContract where fstate = 'AUDIT' and FprojectID='"+projectid+"' and DATE_FORMAT(FsignDate,'%Y') ='"+year+"' ";
			List<Map<String, Object>> yfsAmountList = iCyclePaymentPlanService.executeSqlQuery(yfsAmountsql);
			if(yfsAmountList.size()>0){
				Map<String, Object> map = yfsAmountList.get(0);
				BigDecimal amt = UIRuleUtil.getBigDecimal(map.get("amt"));
				json.put("yfsAmount", amt);
			}
			StringBuffer payAmountsql = new StringBuffer();
			payAmountsql.append(" select sum(a.FtaxReqAmt) reqAmt from yc_cost_paymentReq a ");
			payAmountsql.append(" left join yc_cost_saleContract b on a.FcontractID = b.fid ");
			payAmountsql.append(" where a.fstate = 'AUDIT' and b.FprojectID='"+projectid+"' and DATE_FORMAT(a.FbizDate,'%Y') ='"+year+"' ");
			List<Map<String, Object>> payAmountList = iCyclePaymentPlanService.executeSqlQuery(payAmountsql.toString());
			if(payAmountList.size()>0){
				Map<String, Object> map = payAmountList.get(0);
				BigDecimal reqAmt = UIRuleUtil.getBigDecimal(map.get("reqAmt"));
				json.put("payAmount", reqAmt);
			}
		}
		return json;
	}
}
