package org.springblade.modules.desk.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import org.springblade.common.constant.SystemConstant;
import org.springblade.common.utils.DateUtil;
import org.springblade.core.tool.api.R;
import org.springblade.modules.desk.vo.AccountInStaticVO;
import org.springblade.modules.desk.vo.AccountOutStaticVO;
import org.springblade.modules.desk.vo.AccountStaticVO;
import org.springblade.modules.desk.vo.StaticVO;
import org.springblade.modules.guosen.activity.entity.Activity;
import org.springblade.modules.guosen.activity.service.IActivityService;
import org.springblade.modules.guosen.agenter.entity.Agenter;
import org.springblade.modules.guosen.agenter.service.IAgenterService;
import org.springblade.modules.guosen.billRecord.entity.BillRecord;
import org.springblade.modules.guosen.billRecord.service.IBillRecordService;
import org.springblade.modules.guosen.bussiness.entity.BussinessDebit;
import org.springblade.modules.guosen.bussiness.service.IBussinessDebitService;
import org.springblade.modules.guosen.loginUser.entity.LoginUser;
import org.springblade.modules.guosen.loginUser.service.ILoginUserService;
import org.springblade.modules.guosen.ordercommission.dto.OrderCommissionDTO;
import org.springblade.modules.guosen.ordercommission.entity.OrderCommission;
import org.springblade.modules.guosen.ordercommission.service.IOrderCommissionService;
import org.springblade.modules.guosen.ordercommission.vo.OrderCommissionStaticVO;
import org.springblade.modules.guosen.userPointsGoods.entity.UserPointsGoods;
import org.springblade.modules.guosen.userPointsGoods.service.IUserPointsGoodsService;
import org.springblade.modules.guosen.withdrawRecords.entity.WithdrawRecords;
import org.springblade.modules.guosen.withdrawRecords.service.IWithdrawRecordsService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.rmi.AlreadyBoundException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created By lidexi in 2021/7/2
 * 首页统计
 **/
@RestController
@RequestMapping("/cyzh-static")
@AllArgsConstructor
public class StaticController {

	private final ILoginUserService loginUserService;
	private final IAgenterService agenterService;
	private final IActivityService activityService;
	private final IUserPointsGoodsService userPointsGoodsService;
	private final IOrderCommissionService orderCommissionService;
	private final IBillRecordService billRecordService;
	private final IWithdrawRecordsService withdrawRecordsService;
	private RedisTemplate<String,String> redisTemplate;
	private final IBussinessDebitService bussinessDebitService;
	private final static String ACCOUNT_STATIC = "account:static";
	@GetMapping("static")
	public R<StaticVO> staticVO(){
		StaticVO staticVO = new StaticVO();
		//统计用户总数
		Integer userCount = loginUserService.getBaseMapper().selectCount(new QueryWrapper<>(new LoginUser()));
		staticVO.setUserCount(userCount);
		//统计代理总数
		Integer agenterCount = agenterService.getBaseMapper().selectCount(new QueryWrapper<>(new Agenter()));
		staticVO.setAgenterCount(agenterCount);
		//统计活动总数
		Integer activityCount = activityService.getBaseMapper().selectCount(new QueryWrapper<>(new Activity()));
		staticVO.setActivityCount(activityCount);
		//统计商品总数
		Integer shopCount = userPointsGoodsService.getBaseMapper().selectCount(new QueryWrapper<>(new UserPointsGoods()));
		staticVO.setShopCount(shopCount);

		return R.data(staticVO);
	}

	//统计结算
	@PostMapping("staticOrderCommission")
	public R<OrderCommissionStaticVO> staticOrderCommission(@RequestBody OrderCommissionDTO orderCommissionDTO){
		OrderCommissionStaticVO orderCommissionStaticVO = new OrderCommissionStaticVO();
		Integer staticType = orderCommissionDTO.getStaticType();
		List<String> dateList = new ArrayList<>();
		List<BigDecimal> unClearDataList = new ArrayList<>();
		List<BigDecimal> clearedDataList = new ArrayList<>();
		try {
			if (staticType == 1) {//按日
				dateList = DateUtil.getDateListBetween2Day(orderCommissionDTO.getBeginDate(), orderCommissionDTO.getEndDate(), "yyyy-MM-dd");
			} else if (staticType == 2) {//按月
				dateList = DateUtil.getMonthListBetween2Day(orderCommissionDTO.getBeginDate(), orderCommissionDTO.getEndDate(), "yyyy-MM");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		dateList.forEach(date->{
			List<OrderCommission> unClearOrderCommissions = this.orderCommissionService.getBaseMapper().selectList(new QueryWrapper<>(new OrderCommission()).lambda()
				.like(OrderCommission::getCreateTime, date).eq(OrderCommission::getStatus, SystemConstant.CommissionStatus.PAYING.getValue()));
			BigDecimal decimal = unClearOrderCommissions.stream().map(OrderCommission::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
			unClearDataList.add(decimal);
			List<OrderCommission> clearedOrderCommissions = this.orderCommissionService.getBaseMapper().selectList(new QueryWrapper<>(new OrderCommission()).lambda()
				.like(OrderCommission::getCreateTime, date).eq(OrderCommission::getStatus, SystemConstant.CommissionStatus.PAYED.getValue()));
			BigDecimal decimal1 = clearedOrderCommissions.stream().map(OrderCommission::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
			clearedDataList.add(decimal1);
		});
		orderCommissionStaticVO.setUnClearList(unClearDataList);
		orderCommissionStaticVO.setClearedList(clearedDataList);
		orderCommissionStaticVO.setDateList(dateList);

		return R.data(orderCommissionStaticVO);
	}

	//采购商财务账本
	@GetMapping("/adStaticAccountStatic")
	public R<AccountStaticVO> adStaticAccountStatic(){
		//1、统计历史充值，2、今日充值，3、统计历史付款，4、统计今日付款
		//------------------获取采购商历史充值金额--------------------//
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String today = sdf.format(new Date());
		//1、统计历史充值
		List<BillRecord> billRecords = billRecordService.getBaseMapper().selectList(new QueryWrapper<>(new BillRecord()).lambda()
				.eq(BillRecord::getType, SystemConstant.BillRecordType.ADS.getValue())
				.eq(BillRecord::getPayStatus, SystemConstant.BillRecordPayStatus.PAYED.getValue()));
		AccountInStaticVO historyAdIn = new AccountInStaticVO();
		BigDecimal b1 = billRecords.stream().map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		historyAdIn.setAdsIn(b1);

		//2、今日充值
		BigDecimal b2 = billRecords.stream().filter(record -> sdf.format(record.getCreateTime()).equals(today)).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		AccountInStaticVO todayAdIn = new AccountInStaticVO();
		todayAdIn.setAdsIn(b2);

		//------------------获取采购商历史付款金额--------------------//
		//3、统计历史付款
		List<BussinessDebit> bussinessDebits = bussinessDebitService.getBaseMapper().selectList(new QueryWrapper<>(new BussinessDebit()).lambda()
				.eq(BussinessDebit::getType, SystemConstant.BussinessDebitType.COMMISSION.getValue())
				.eq(BussinessDebit::getStatus, SystemConstant.BussinessDebitStatus.SUCCESS.getValue()));
		AccountOutStaticVO historyAdOut = new AccountOutStaticVO();
		BigDecimal b3 = bussinessDebits.stream().map(BussinessDebit::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		historyAdOut.setAdsOut(b3);

		//4、统计今日付款
		BigDecimal b4 = bussinessDebits.stream().filter(debit -> sdf.format(debit.getCreateTime()).equals(today)).map(BussinessDebit::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		AccountOutStaticVO todayAdOut = new AccountOutStaticVO();
		todayAdOut.setAdsOut(b4);

		AccountStaticVO accountStaticVO = new AccountStaticVO();
		accountStaticVO.setTotalIn(historyAdIn);
		accountStaticVO.setTodayIn(todayAdIn);
		accountStaticVO.setTotalOut(historyAdOut);
		accountStaticVO.setTodayOut(todayAdOut);
		return R.data(accountStaticVO);
	}


	//财务账本
	@GetMapping("/staticAccountStatic")
	public R<AccountStaticVO> staticAccountStatic(){
		Date now = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		//从缓存中获取历史提现数据
		String historyOutData =redisTemplate.opsForValue().get(ACCOUNT_STATIC+":out");
		AccountOutStaticVO historyOutStatic = new AccountOutStaticVO();
		if(historyOutData != null){
			historyOutStatic = JSON.parseObject(historyOutData, AccountOutStaticVO.class);
		}
		//从缓存中获取历史收入数据
		String historyInData =redisTemplate.opsForValue().get(ACCOUNT_STATIC+":in");
		AccountInStaticVO historyInStatic = new AccountInStaticVO();
		if(historyInData != null){
			historyInStatic = JSON.parseObject(historyInData, AccountInStaticVO.class);
		}else{
			//统计历史收益信息

			//获取今日之前的支付记录
			List<BillRecord> billRecords = billRecordService.getBaseMapper().selectList(new QueryWrapper<>(new BillRecord()).lambda()
				.lt(BillRecord::getCreateTime,sdf.format(now)).eq(BillRecord::getPayStatus,SystemConstant.BillRecordPayStatus.PAYED.getValue()).ne(BillRecord::getType, SystemConstant.BillRecordType.ADS.getValue()));
			//统计历史用户支付记录
			BigDecimal historyUserIn = billRecords.stream().filter(billRecord ->
				SystemConstant.BillRecordType.SHOPPING.getValue() == billRecord.getType() ||
					SystemConstant.BillRecordType.AUTHOR_REWARD.getValue() == billRecord.getType() ||
					SystemConstant.BillRecordType.PRODUCT_REWARD.getValue() == billRecord.getType()
			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			historyInStatic.setUserIn(historyUserIn);

			//统计历史代理支付记录
			BigDecimal historyAgenterIn = billRecords.stream().filter(billRecord ->
				SystemConstant.BillRecordType.AGENTER.getValue() == billRecord.getType()
			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			//统计历史采购商支付记录
			BigDecimal historyAdIn = billRecords.stream().filter(billRecord ->
				SystemConstant.BillRecordType.ADS.getValue() == billRecord.getType()
			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			historyInStatic.setProxyIn(historyAgenterIn);
			historyInStatic.setAdsIn(historyAdIn);
			historyInStatic.setTotal(historyUserIn.add(historyAgenterIn).add(historyAdIn));
		}

		AccountStaticVO accountStaticVO = new AccountStaticVO();

		accountStaticVO.setTotalIn(historyInStatic);
		accountStaticVO.setTotalOut(historyOutStatic);
		try{

			/**
			 * 	当日的支付记录
			 */

			List<BillRecord> billRecords = billRecordService.getBaseMapper().selectList(new QueryWrapper<>(new BillRecord()).lambda()
				.gt(BillRecord::getCreateTime,sdf.format(now)).eq(BillRecord::getPayStatus,SystemConstant.BillRecordPayStatus.PAYED.getValue()));
			//统计当日用户支付记录
			BigDecimal todayUserIn = billRecords.stream().filter(billRecord ->
				SystemConstant.BillRecordType.SHOPPING.getValue() == billRecord.getType() ||
					SystemConstant.BillRecordType.AUTHOR_REWARD.getValue() == billRecord.getType() ||
					SystemConstant.BillRecordType.PRODUCT_REWARD.getValue() == billRecord.getType()
			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			//统计当日代理支付记录
			BigDecimal todayAgenterIn = billRecords.stream().filter(billRecord ->
				SystemConstant.BillRecordType.AGENTER.getValue() == billRecord.getType()
			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			//统计当日采购商支付记录
//			BigDecimal todayAdIn = billRecords.stream().filter(billRecord ->
//				SystemConstant.BillRecordType.ADS.getValue() == billRecord.getType()
//			).map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

			AccountInStaticVO todayIn = new AccountInStaticVO();
//			todayIn.setAdsIn(todayAdIn);
			todayIn.setProxyIn(todayAgenterIn);
			todayIn.setUserIn(todayUserIn);
			todayIn.setTotal(todayAgenterIn.add(todayUserIn));

			accountStaticVO.setTodayIn(todayIn);
			/**
			 * 统计当日的提现记录
			 */
			List<WithdrawRecords> withdrawRecords = withdrawRecordsService.getBaseMapper().selectList(new QueryWrapper<>(new WithdrawRecords())
				.lambda().gt(WithdrawRecords::getCreateTime,sdf.format(now)).eq(WithdrawRecords::getWithdrawStatus,1));

			//统计当日用户提现
			BigDecimal todayUserOut = withdrawRecords.stream().filter(withdrawRecord ->
				SystemConstant.WithdrawRecordType.USER.getValue() == withdrawRecord.getType()
			).map(WithdrawRecords::getCashValue).reduce(BigDecimal.ZERO, BigDecimal::add);
			//统计当日代理提现
			BigDecimal todayAgenterOut = withdrawRecords.stream().filter(withdrawRecord ->
				SystemConstant.WithdrawRecordType.AGENTER.getValue() == withdrawRecord.getType()
			).map(WithdrawRecords::getCashValue).reduce(BigDecimal.ZERO, BigDecimal::add);
			//统计当日采购商提现
//			BigDecimal todayAdsOut = withdrawRecords.stream().filter(withdrawRecord ->
//				SystemConstant.WithdrawRecordType.ADS.getValue() == withdrawRecord.getType()
//			).map(WithdrawRecords::getCashValue).reduce(BigDecimal.ZERO, BigDecimal::add);
			//统计当日主办方提现
			BigDecimal todaySponsorOut = withdrawRecords.stream().filter(withdrawRecord ->
				SystemConstant.WithdrawRecordType.SPONSOR.getValue() == withdrawRecord.getType()
			).map(WithdrawRecords::getCashValue).reduce(BigDecimal.ZERO, BigDecimal::add);
			//统计当日运营方提现
			BigDecimal todayOperationOut = withdrawRecords.stream().filter(withdrawRecord ->
				SystemConstant.WithdrawRecordType.OPERATION.getValue() == withdrawRecord.getType()
			).map(WithdrawRecords::getCashValue).reduce(BigDecimal.ZERO, BigDecimal::add);

			AccountOutStaticVO todayOut = new AccountOutStaticVO();
			todayOut.setUserOut(todayUserOut);
			todayOut.setProxyOut(todayAgenterOut);
//			todayOut.setAdsOut(todayAdsOut);
			todayOut.setSponsorOut(todaySponsorOut);
			todayOut.setOperationOut(todayOperationOut);

			accountStaticVO.setTodayOut(todayOut);

		}catch (Exception e){
			e.printStackTrace();
		}

		return R.data(accountStaticVO);
	}


}
