/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.guosen.bonusgroupdailystatic.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;

import org.apache.ibatis.annotations.Param;
import org.springblade.common.constant.SystemConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.guosen.billRecord.entity.BillRecord;
import org.springblade.modules.guosen.billRecord.service.IBillRecordService;
import org.springblade.modules.guosen.bonusgroup.entity.BonusGroup;
import org.springblade.modules.guosen.bonusgroup.service.IBonusGroupService;
import org.springblade.modules.guosen.bonusscene.entity.BonusScene;
import org.springblade.modules.guosen.bonusscene.service.IBonusSceneService;
import org.springblade.modules.guosen.bussiness.entity.Bussiness;
import org.springblade.modules.guosen.bussiness.service.IBussinessService;
import org.springblade.modules.system.service.IParamService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.guosen.bonusgroupdailystatic.entity.BonusGroupDailyStatic;
import org.springblade.modules.guosen.bonusgroupdailystatic.vo.BonusGroupDailyStaticVO;
import org.springblade.modules.guosen.bonusgroupdailystatic.wrapper.BonusGroupDailyStaticWrapper;
import org.springblade.modules.guosen.bonusgroupdailystatic.service.IBonusGroupDailyStaticService;
import org.springblade.core.boot.ctrl.BladeController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 分润组每日分润金额统计 控制器
 *
 * @author BladeX
 * @since 2021-11-13
 */
@RestController
@AllArgsConstructor
@RequestMapping("cyzh-bonus-group-daily-static/bonusgroupdailystatic")
@Api(value = "分润组每日分润金额统计", tags = "分润组每日分润金额统计接口")
public class BonusGroupDaliyStaticController extends BladeController {

	private final IBonusGroupDailyStaticService bonusGroupDailyStaticService;
	private final IBonusSceneService sceneService;
	private final IBussinessService bussinessService;
	private final IBonusGroupService bonusGroupService;
	private final IBillRecordService billRecordService;
	private final IParamService paramService;


	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入bonusGroupDaliyStatic")
	public R<BonusGroupDailyStaticVO> detail(BonusGroupDailyStatic bonusGroupDaliyStatic) {
		BonusGroupDailyStatic detail = bonusGroupDailyStaticService.getOne(Condition.getQueryWrapper(bonusGroupDaliyStatic));
		return R.data(BonusGroupDailyStaticWrapper.build().entityVO(detail));
	}

	/**
	 * 分页 分润组每日分润金额统计
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入bonusGroupDaliyStatic")
	public R<IPage<BonusGroupDailyStaticVO>> list(BonusGroupDailyStatic bonusGroupDailyStatic, Query query) {
		BladeUser bladeUser = AuthUtil.getUser();
		if(bladeUser.getRoleName().equals("财务管理") || bladeUser.getRoleName().equals("administrator")){
			Date bonusDate = bonusGroupDailyStatic.getBonusDate();
			String dateFormat = null;
			if(bonusDate != null){
				bonusGroupDailyStatic.setBonusDate(null);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				dateFormat = sdf.format(bonusDate);
			}
			LambdaQueryWrapper<BonusGroupDailyStatic> lambda = Condition.getQueryWrapper(bonusGroupDailyStatic).lambda();
			lambda.like(bonusDate != null, BonusGroupDailyStatic::getBonusDate, dateFormat);
			lambda.eq(bonusGroupDailyStatic.getBonusGroupId() != null, BonusGroupDailyStatic::getBonusGroupId, bonusGroupDailyStatic.getBonusGroupId());
			IPage<BonusGroupDailyStatic> pages = bonusGroupDailyStaticService.page(Condition.getPage(query), lambda);
			return R.data(BonusGroupDailyStaticWrapper.build().pageVO(pages));
		}else{
			return R.fail("无权限查看");
		}
	}


	/**
	 * 自定义分页 分润组每日分润金额统计
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入bonusGroupDaliyStatic")
	public R<IPage<BonusGroupDailyStaticVO>> page(BonusGroupDailyStaticVO bonusGroupDailyStatic, Query query) {
		IPage<BonusGroupDailyStaticVO> pages = bonusGroupDailyStaticService.selectBonusGroupDaliyStaticPage(Condition.getPage(query), bonusGroupDailyStatic);
		return R.data(pages);
	}

	/**
	 * 新增 分润组每日分润金额统计
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入bonusGroupDaliyStatic")
	public R save(@Valid @RequestBody BonusGroupDailyStatic bonusGroupDailyStatic) {
		return R.status(bonusGroupDailyStaticService.save(bonusGroupDailyStatic));
	}

	/**
	 * 修改 分润组每日分润金额统计
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入bonusGroupDaliyStatic")
	public R update(@Valid @RequestBody BonusGroupDailyStatic bonusGroupDailyStatic) {
		return R.status(bonusGroupDailyStaticService.updateById(bonusGroupDailyStatic));
	}

	/**
	 * 新增或修改 分润组每日分润金额统计
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入bonusGroupDaliyStatic")
	public R submit(@Valid @RequestBody BonusGroupDailyStatic bonusGroupDailyStatic) {
		return R.status(bonusGroupDailyStaticService.saveOrUpdate(bonusGroupDailyStatic));
	}

	
	/**
	 * 删除 分润组每日分润金额统计
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(bonusGroupDailyStaticService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * 删除 分润组每日分润金额统计
	 */
	@PostMapping("/bonus")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "报表分润")
	public R bonus(@RequestBody BonusGroupDailyStatic bonusGroupDailyStatic) {
		BladeUser user = AuthUtil.getUser();
		if(!(user.getRoleName().equals("财务管理") || user.getRoleName().equals("administrator"))){//运营查询平台商余额
			return R.fail("无权限操作");
		}
		BonusGroupDailyStatic dailyStatic = this.bonusGroupDailyStaticService.getById(bonusGroupDailyStatic.getId());
		if(dailyStatic == null){
			return R.fail("报表统计记录不存在");
		}
		BonusScene scene = sceneService.getById(dailyStatic.getBonusSceneId());
		if(scene == null){
			return R.fail("业务场景不存在");
		}
		Long platformBussinessId = scene.getPlatformBussinessId();
		Long bonusGroupId = dailyStatic.getBonusGroupId();
		BonusGroup group = this.bonusGroupService.getById(bonusGroupId);
		Bussiness bussiness = this.bussinessService.getById(group.getBussinessId());
		Bussiness parentBussiness = this.bussinessService.getById(platformBussinessId);
		if(bussiness == null){
			return R.fail("平台商不存在");
		}
		return this.bonusGroupDailyStaticService.bonus(bonusGroupDailyStatic.getId(), bussiness, parentBussiness);
	}

	/**
	 * 生成指定日期的统计报表
	 */
	@PostMapping("/generateDailyStatic")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "报表分润")
	public R generateDailyStatic(@Param(value = "beginDateStr") String beginDateStr, @Param(value = "endDateStr") String endDateStr) {
		Date beginDate = DateUtil.parse(beginDateStr, "yyyy-MM-dd");
		Date endDate = DateUtil.parse(endDateStr, "yyyy-MM-dd");
		String fromDateStr = beginDateStr;
		BigDecimal baseRate = new BigDecimal(paramService.getValue("yee_base_rate")).multiply(new BigDecimal(10));//0.21 * 10 = 2.1
		BigDecimal saasBaseRate = new BigDecimal(paramService.getValue("yee_saas_rate")).multiply(new BigDecimal(10));//0.1 * 10 = 1
		BigDecimal yeeRate = (baseRate.add(saasBaseRate)).divide(new BigDecimal(1000));
		while(beginDate.before(DateUtil.plusDays(endDate, 1))){
			//查询昨日充值账单
			List<BillRecord> billRecordList = billRecordService.getBaseMapper().selectList(new QueryWrapper<>(new BillRecord()).lambda()
							.eq(BillRecord::getType, SystemConstant.BillRecordType.ADS.getValue()).like(BillRecord::getCreateTime, fromDateStr)
							.eq(BillRecord::getPayStatus, SystemConstant.BillRecordPayStatus.PAYED.getValue()));
			//按照采购单所属平台商分类统计
			Map<Long, List<BillRecord>> billRecordMap = billRecordList.stream().collect(Collectors.groupingBy(BillRecord::getUserId, Collectors.toList()));
			for(Long bussinessId : billRecordMap.keySet()){
				List<BillRecord> sceneBillRecordList = billRecordMap.get(bussinessId);
				BigDecimal rechargeAmt = sceneBillRecordList.stream().map(BillRecord::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal rechargeServiceFee = sceneBillRecordList.stream().map(BillRecord::getBussinessFee).reduce(BigDecimal.ZERO, BigDecimal::add);
				//计算支付渠道手续费
				BigDecimal rechargeFee = sceneBillRecordList.stream().map(record -> record.getPrice().multiply(yeeRate)).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal bonusAmt = rechargeServiceFee.subtract(rechargeFee);
				Integer rechargeCount = sceneBillRecordList.size();
				Bussiness bussiness = this.bussinessService.getById(bussinessId);
				this.bonusGroupDailyStaticService.generateDailyStatic(bussiness.getParentBussinessId(), bussinessId, rechargeAmt, rechargeServiceFee, rechargeFee, rechargeCount, bonusAmt, beginDate);
			}
			beginDate = DateUtil.plusDays(beginDate, 1);
			fromDateStr = DateUtil.format(beginDate, "yyyy-MM-dd");
		}
		return R.status(true);
	}

}
