package com.cku.oa.finance.web;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.cku.logUtil.JSONObjectUtils;
import com.cku.oa.constant.Constants;
import com.cku.oa.finance.entity.*;
import com.cku.oa.finance.service.PaymentOrderService;
import com.cku.oa.finance.service.PaymentRecordService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.oa.finance.dao.MemberAccountDao;
import com.cku.oa.finance.dao.PaymentOrderDetailDao;
import com.cku.oa.finance.service.MemberAccountService;
import com.cku.oa.finance.service.PaymentChargingItemService;
import com.cku.oa.statistics.service.ShowOfficeRegionService;
import com.cku.oa.statistics.vo.RegionVo;
import com.cku.oa.sys.dao.user.MemberDao;
import com.cku.oa.sys.entity.user.Member;
import com.cku.oa.sys.service.user.MemberService;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;

/**
 * Created with IntelliJ IDEA.
 * User: lyy
 * Date: 2016/7/25
 * Time: 17:25
 */

/**
 * 会员账户controller
 */
@Controller
@RequestMapping(value = "${adminPath}/finance/memberAccount")
public class MemberAccountController extends BaseController {
	@Autowired
	private MemberAccountService memberAccountService;
	@Autowired
	private PaymentChargingItemService paymentChargingItemService;
	@Autowired
	private MemberDao memberDao;
	@Autowired
	private MemberService memberService;
	@Autowired
	private MemberAccountDao memberAccountDao;
	@Autowired
	private PaymentOrderDetailDao paymentOrderDetailDao;
	@Autowired
	private ShowOfficeRegionService showOfficeRegionService;

	@Autowired
	private PaymentRecordService paymentRecordService;

	@Autowired
	private PaymentOrderService paymentOrderService;

	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = { "list", "" })
	public String list(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		/*
		 * if(!RequestUtil.hasParameter(request)){ //没有参数的查询，默认只查询最近的三个月 Calendar
		 * calendar = Calendar.getInstance();//日历对象 Date date = new Date();
		 * date.setHours(0); date.setMinutes(0); date.setSeconds(0);
		 * calendar.setTime(date);//设置当前日期 calendar.add(Calendar.MONTH, -3);//年份+1
		 * memberAccount.setPaymentTimeStart(calendar.getTime()); }
		 */
		boolean clear = false;
		if (StringUtils.isBlank(memberAccount.getRunningNumber()) && StringUtils.isBlank(memberAccount.getCmember())
				&& StringUtils.isBlank(memberAccount.getMemberCode())
				&& StringUtils.isBlank(memberAccount.getMemberName())
				&& StringUtils.isBlank(memberAccount.getChargingItemOfficeId())
				&& StringUtils.isBlank(memberAccount.getPaymentWay())
				&& StringUtils.isBlank(memberAccount.getChargingItemId()) && null == memberAccount.getUpdateBy()
				&& StringUtils.isBlank(memberAccount.getPaymentAmount())
				&& StringUtils.isBlank(memberAccount.getPaymentRemarks())) {
			// 没有参数的查询，默认只查询最近的半个月
			Calendar calendar = Calendar.getInstance();// 日历对象
			Date date = new Date();
			date.setHours(0);
			date.setMinutes(0);
			date.setSeconds(0);
			calendar.setTime(date);// 设置当前日期
			/* calendar.add(Calendar.MONTH, -1);//年份+1 */
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			memberAccount.setPaymentTimeStart(calendar.getTime());
			clear = true;
		}
		String countPrice = memberAccountService.getCountPrice(memberAccount);
		Page<MemberAccount> page = memberAccountService.findPage(new Page<MemberAccount>(request, response),
				memberAccount);
		model.addAttribute("chargingItems", paymentChargingItemService.findAllList(new PaymentChargingItem()));
		/*
		 * if(!RequestUtil.hasParameter(request)){
		 * memberAccount.setPaymentTimeStart(null); }
		 */
		if (clear) {
			memberAccount.setPaymentTimeStart(null);
		}
		List<String> runningMembers = page.getList().stream().map(MemberAccount::getRunningNumber).collect(Collectors.toList());
		List<PaymentOrder> byRunningMembers = paymentOrderService.findByRunningMembers(runningMembers);
		Map<String, PaymentOrder> stringPaymentOrderMap = new HashMap<>();
		if (CollectionUtils.isNotEmpty(byRunningMembers)) {
			stringPaymentOrderMap = byRunningMembers.stream().collect(Collectors.toMap(PaymentOrder::getOrderCode, Function.identity()));
		}

		for (MemberAccount m : page.getList()) {
			// if (StringUtils.isBlank(m.getBalanceMoney())) {
			// 查询当前余额
			String memberCode = StringUtils.isNotBlank(m.getCmember()) ? m.getCmember() : StringUtils.isNotBlank(m.getOrgmember())?m.getOrgmember():m.getMemberCode();
			Member member = memberDao
					.getByMemberCode(memberCode);
			// 查询 截止订单日期 用户充值金额。
			MemberAccount c = new MemberAccount();
			c.setMemberCode(memberCode);
			c.setPaymentTimeStart(m.getPaymentTime());
			double chongZhiMoney = memberAccountDao.getChongZhiMoney(c);
			// 第三部，查询截止订单日期 用户用 用户余额支付的
			double hufeiMoney = memberAccountDao.getHuaMoney(c);
			// 进行加减运算
			BigDecimal b1 = BigDecimal.ZERO;
			if (member != null) {
				b1 = new BigDecimal(member.getAccountBalance());
			}

			BigDecimal b2 = new BigDecimal(chongZhiMoney);
			BigDecimal b3 = new BigDecimal(hufeiMoney);
			BigDecimal result = b1.subtract(b2).add(b3).setScale(2, BigDecimal.ROUND_HALF_UP);
			m.setBalanceMoneyReal(m.getBalanceMoney());
			m.setBalanceMoney(result.toString());
			/*
			 * Map map =memberDao.findeOne(m.getMemberCode(),m.getPaymentTime());
			 * if(null!=map&&null!=map.get("before_change")&&null!=map.get("change_amount"))
			 * { BigDecimal beforeChange = new
			 * BigDecimal(map.get("before_change").toString()); BigDecimal changeMoney = new
			 * BigDecimal(map.get("change_amount").toString()); BigDecimal
			 * money=beforeChange.add(changeMoney); m.setBalanceMoney(money.toString());
			 * }else{ m.setBalanceMoney("0.00"); }
			 */

			PaymentOrderDetail paymentOrderDetail = paymentOrderDetailDao.getByOrderCode(m.getRunningNumber());
			if (null != paymentOrderDetail) {
				m.setVoucherCode(paymentOrderDetail.getVoucherCode());
				m.setBusinessRefundState(paymentOrderDetail.getBusinessRefundState());
			}
			if (MapUtils.isNotEmpty(stringPaymentOrderMap)) {
				PaymentOrder paymentOrder = stringPaymentOrderMap.get(m.getRunningNumber());
				logger.info("会员明细列表根据流水号查询会员支付订单 : {}", JSONObjectUtils.toJsonString(paymentOrder));
				if (Objects.nonNull(paymentOrder)) {
					m.setOrderCancelStatus(paymentOrder.getDelFlag());
				}
			}

			// }

			// 修改系统管理员名称
			if ("1".equals(m.getUpdateBy().getId())) {
				m.getUpdateBy().setName("系统管理员");
			}
			// 判断该条数据是否属于当前用户
			if (Objects.equals(m.getCreateBy().getId(), UserUtils.getLoginUser().getId())) {
				m.setOwner(Boolean.TRUE);
			}
		}
		model.addAttribute("countPrice", countPrice);
		model.addAttribute("page", page);
		model.addAttribute("payType", memberAccount.getPaymentWay());

		if (null != memberAccount.getSearcheType() && memberAccount.getSearcheType().equals("1")) {
			if (page.getList() != null && page.getList().size() > 0) {
				Member member = memberService.getByMemberCode(page.getList().get(0).getMemberCode());
				model.addAttribute("member", member);
			}
			return "oa/finance/memberSearch";
		} else {
			return "oa/finance/memberAccountDetailList";
		}
	}

	@RequiresPermissions("finance:memberAccount:editRemark")
	@RequestMapping(value = "/editRemark/form")
	public String editRemarkForm(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
						   Model model){
		logger.info("MemberAccountController editRemarkForm runningNumber : {}, numberCode : {},  model : {}"
				, memberAccount.getRunningNumber(), memberAccount.getMemberCode());
		List<MemberAccount> memberAccountList = memberAccountService.findList(memberAccount);
		logger.info("MemberAccountController editRemarkForm memberAccountService.findList result : {}", JSON.toJSONString(memberAccountList));
		if (CollectionUtils.isEmpty(memberAccountList)) {
			throw new RuntimeException("根据orderCode查询会员信息为Null,请检查!");
		}
		model.addAttribute("memberAccount", memberAccountList.get(Constants.NUM_ZERO));
		return "oa/finance/memberAccountDetailEditRemarkForm";
	}

	@RequiresPermissions("finance:memberAccount:editRemark")
	@RequestMapping(value = "/editRemark")
	public void editRemark(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
							 Model model) throws IOException {
		/*logger.info("MemberAccountController editRemark param : {}, model : {}", JSON.toJSONString(memberAccount), JSON.toJSONString(model));*/

		JSONObject result = new JSONObject();
		// 查询会员
		try {
			memberAccountService.savePaymentRemarks(memberAccount.getRunningNumber(), memberAccount.getPaymentRemarks());
			String mes = "会员：" + memberAccount.getMemberCode() + "修改支付备注成功！";
			result.put("rc", 0);
			result.put("msg", mes);
			result.put("successUrl", "/finance/memberAccount");
		} catch (Exception e) {
			result.put("rc", 1);
			result.put("msg", e.getMessage());

		}
		response.setContentType("application/json;charset=UTF-8");
		response.getWriter().write(result.toString());
	}

	@RequestMapping(value = { "regionList" })
	public String regionList(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		/*
		 * if(!RequestUtil.hasParameter(request)){ //没有参数的查询，默认只查询最近的三个月 Calendar
		 * calendar = Calendar.getInstance();//日历对象 Date date = new Date();
		 * date.setHours(0); date.setMinutes(0); date.setSeconds(0);
		 * calendar.setTime(date);//设置当前日期 calendar.add(Calendar.MONTH, -3);//年份+1
		 * memberAccount.setPaymentTimeStart(calendar.getTime()); }
		 */
		boolean clear = false;
		if (StringUtils.isBlank(memberAccount.getRunningNumber()) && StringUtils.isBlank(memberAccount.getCmember())
				&& StringUtils.isBlank(memberAccount.getMemberCode())
				&& StringUtils.isBlank(memberAccount.getMemberName())
				&& StringUtils.isBlank(memberAccount.getChargingItemOfficeId())
				&& StringUtils.isBlank(memberAccount.getPaymentWay())
				&& StringUtils.isBlank(memberAccount.getChargingItemId()) && null == memberAccount.getUpdateBy()
				&& StringUtils.isBlank(memberAccount.getPaymentAmount())
				&& StringUtils.isBlank(memberAccount.getPaymentRemarks())) {
			// 没有参数的查询，默认只查询最近的半个月
			Calendar calendar = Calendar.getInstance();// 日历对象
			Date date = new Date();
			date.setHours(0);
			date.setMinutes(0);
			date.setSeconds(0);
			calendar.setTime(date);// 设置当前日期
			/* calendar.add(Calendar.MONTH, -1);//年份+1 */
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			memberAccount.setPaymentTimeStart(calendar.getTime());
			clear = true;
		}
		if(StringUtils.isEmpty(memberAccount.getProvince())) {
			List<RegionVo> regions = showOfficeRegionService.findRegionList();
			memberAccount.setRegions(regions);
		}
		String countPrice = memberAccountService.getCountPrice(memberAccount);
		Page<MemberAccount> page = memberAccountService.findPage(new Page<MemberAccount>(request, response),
				memberAccount);
		model.addAttribute("chargingItems", paymentChargingItemService.findAllList(new PaymentChargingItem()));
		/*
		 * if(!RequestUtil.hasParameter(request)){
		 * memberAccount.setPaymentTimeStart(null); }
		 */
		if (clear) {
			memberAccount.setPaymentTimeStart(null);
		}
		for (MemberAccount m : page.getList()) {
			// if (StringUtils.isBlank(m.getBalanceMoney())) {
			// 查询当前余额
			Member member = memberDao
					.getByMemberCode(StringUtils.isNotBlank(m.getCmember()) ? m.getCmember() : m.getMemberCode());
			// 查询 截止订单日期 用户充值金额。
			MemberAccount c = new MemberAccount();
			c.setMemberCode(StringUtils.isNotBlank(m.getCmember()) ? m.getCmember() : m.getMemberCode());
			c.setPaymentTimeStart(m.getPaymentTime());
			double chongZhiMoney = memberAccountDao.getChongZhiMoney(c);
			// 第三部，查询截止订单日期 用户用 用户余额支付的
			double hufeiMoney = memberAccountDao.getHuaMoney(c);
			// 进行加减运算
			BigDecimal b1 = BigDecimal.ZERO;
			if (member != null) {
				b1 = new BigDecimal(member.getAccountBalance());
			}

			BigDecimal b2 = new BigDecimal(chongZhiMoney);
			BigDecimal b3 = new BigDecimal(hufeiMoney);
			BigDecimal result = b1.subtract(b2).add(b3).setScale(2, BigDecimal.ROUND_HALF_UP);
			m.setBalanceMoney(result.toString());
			/*
			 * Map map =memberDao.findeOne(m.getMemberCode(),m.getPaymentTime());
			 * if(null!=map&&null!=map.get("before_change")&&null!=map.get("change_amount"))
			 * { BigDecimal beforeChange = new
			 * BigDecimal(map.get("before_change").toString()); BigDecimal changeMoney = new
			 * BigDecimal(map.get("change_amount").toString()); BigDecimal
			 * money=beforeChange.add(changeMoney); m.setBalanceMoney(money.toString());
			 * }else{ m.setBalanceMoney("0.00"); }
			 */

			PaymentOrderDetail paymentOrderDetail = paymentOrderDetailDao.getByOrderCode(m.getRunningNumber());
			if (null != paymentOrderDetail) {
				m.setVoucherCode(paymentOrderDetail.getVoucherCode());
				m.setBusinessRefundState(paymentOrderDetail.getBusinessRefundState());
			}
			// }

			// 修改系统管理员名称
			if ("1".equals(m.getUpdateBy().getId())) {
				m.getUpdateBy().setName("系统管理员");
			}
		}
		model.addAttribute("countPrice", countPrice);
		model.addAttribute("page", page);
		model.addAttribute("payType", memberAccount.getPaymentWay());

		return "oa/finance/regionMemberAccountDetailListPage";
	}

	/**
	 * 地方俱乐部代办 明细
	 * 
	 * @param memberAccount
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = "org")
	public String orgList(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		if (StringUtils.isNotBlank(memberAccount.getMemberCode()) && memberAccount.getMemberCode().indexOf("HZ") > -1) {
			String countPrice = memberAccountService.getOrgCountPrice(memberAccount);
			Page<MemberAccount> page = memberAccountService.findOrgPage(new Page<MemberAccount>(request, response),
					memberAccount);
			model.addAttribute("countPrice", countPrice);
			model.addAttribute("page", page);
			model.addAttribute("noCode", false);
		} else {
			model.addAttribute("noCode", true);
		}

		return "oa/finance/orgAgencyDetailList";
	}

	/**
	 * 美容学校代办 明细
	 * 
	 * @param memberAccount
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = "training")
	public String trainingList(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		if (StringUtils.isNotBlank(memberAccount.getMemberCode())
				&& memberAccount.getMemberCode().indexOf("MRHZ") > -1) {
			String countPrice = memberAccountService.getTrainingCountPrice(memberAccount);
			Page<MemberAccount> page = memberAccountService.findTrainingPage(new Page<MemberAccount>(request, response),
					memberAccount);
			model.addAttribute("countPrice", countPrice);
			model.addAttribute("page", page);
			model.addAttribute("noCode", false);
		} else {
			model.addAttribute("noCode", true);
		}

		return "oa/finance/trainingAgencyDetailList";
	}

	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = "form")
	public String form(MemberAccount memberAccount, Model model) {
		model.addAttribute("memberAccount", memberAccount);
		model.addAttribute("today", new Date());
		return "oa/finance/memberAccountDetailForm";
	}

	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = "formReserve")
	public String formReserve(MemberAccount memberAccount, Model model) {
		model.addAttribute("memberAccount", memberAccount);
		model.addAttribute("today", new Date());
		return "oa/finance/memberAccountDetailFormReserve";
	}

	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = { "search" })
	public String search(MemberAccount memberAccount, HttpServletRequest request, HttpServletResponse response,
			Model model) {
		/*
		 * Page<Member> page = new Page<Member>(); if(member.getMemberCode() != null &&
		 * member.getName() != null){
		 *//*
			 * page = memberService.findPage(new Page<Member>(request, response), member);
			 *//*
				 * }
				 */
		Page<MemberAccount> page = new Page<MemberAccount>();
		if (StringUtils.isNotBlank(memberAccount.getRunningNumber())) {
			page = memberAccountService.findPage(new Page<MemberAccount>(request, response), memberAccount);
		}
		model.addAttribute("page", page);
		return "oa/finance/memberSearch";
	}

	@RequiresPermissions("finance:memberAccount:recharge")
	@RequestMapping(value = "rechargeAccount")
	public String rechargeAccount(MemberAccount memberAccount, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, memberAccount)) {
			return form(memberAccount, model);
		}
		try {
			memberAccountService.rechargeAccount(memberAccount);
			addMessage(redirectAttributes, "会员充值成功");
		} catch (ZAException e) {
			addMessage(redirectAttributes, e.getMessage());
		}
		return "redirect:" + Global.getAdminPath() + "/finance/memberAccount/?repage";
	}

	/**
	 * 反向加入流水
	 * 
	 * @param memberAccount
	 * @param model
	 * @param redirectAttributes
	 * @return
	 */
	@RequiresPermissions("finance:memberAccount:recharge")
	@RequestMapping(value = "rechargeAccountReverse")
	public String rechargeAccountReverse(MemberAccount memberAccount, Model model,
			RedirectAttributes redirectAttributes) {
		try {
			memberAccount.setRunningNumber(memberAccount.getRunningNumberReverse());
			MemberAccount memberAccount1 = memberAccountDao.findOne(memberAccount).get(0);
			if (memberAccount1.getPaymentState().equals("3")) {
				throw new ZAException(ZAErrorCode.ZA_ERROR, "反充失败，已经反冲过了");
			}
			MemberAccount memberAccount2 = new MemberAccount();
			memberAccount2.setId(memberAccount1.getId());
			memberAccount1.setPaymentRemarks(memberAccount.getPaymentRemarks());
			memberAccount1.setRunningNumberReverse(memberAccount.getRunningNumberReverse());
			if (memberAccount1.getPaymentAmount().contains("-")) {
				memberAccount1.setPaymentAmount(Math.abs(Double.parseDouble(memberAccount1.getPaymentAmount())) + "");
			} else {
				memberAccount1.setPaymentAmount("-" + memberAccount1.getPaymentAmount());
			}
			memberAccount1.setPaymentTime(new Date());
			memberAccount1.setId("");
			memberAccountService.rechargeAccountReserve(memberAccount1, memberAccount2);
			addMessage(redirectAttributes, "会员充值成功");
		} catch (ZAException e) {
			addMessage(redirectAttributes, e.getMessage());
		}
		return "redirect:" + Global.getAdminPath() + "/finance/memberAccount/?repage";
	}

	@RequestMapping(value = "export", method = RequestMethod.POST)
	public String export(MemberAccount memberAccount, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		try {
			memberAccountService.export(memberAccount, response);
		} catch (Exception e) {
			addMessage(redirectAttributes, "导出资格收支明细失败！失败信息：" + e.getMessage());
		}
		return null;
	}

	@RequiresPermissions("finance:memberAccount:view")
	@RequestMapping(value = "searchStatisticsDetail")
	public String searchStatisticsDetail(MemberAccount memberAccount, HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String countPrice = memberAccountService.searchStatisticsDetailCountPrice(memberAccount);
		Page<MemberAccount> page = memberAccountService
				.searchStatisticsDetailPage(new Page<MemberAccount>(request, response), memberAccount);
		model.addAttribute("countPrice", countPrice);
		model.addAttribute("page", page);
		return "oa/finance/memberBalanceStatisticsDetailList";
	}
}
