package org.springblade.gateway.common_gateway.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springblade.common.enums.AppConstant;
import org.springblade.common.enums.CsFlag;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.api.R;
import org.springblade.gateway.common_gateway.entity.dto.BillStatisticsDTO;
import org.springblade.gateway.common_gateway.entity.vo.AppBillsVO;
import org.springblade.gateway.common_gateway.entity.vo.BillStatisticsVO;
import org.springblade.gateway.common_gateway.wrapper.AppBillsWrapper;
import org.springblade.ldt.bills.entity.Bills;
import org.springblade.ldt.bills.service.IBillsService;
import org.springblade.ldt.shop.service.IShopService;
import org.springblade.ldt.user.service.ILoginUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author cy-computer
 */
@Api(tags = "账单模块")
@RestController
@RequestMapping("/common/bills")
@AllArgsConstructor
public class AppBillsController {

	private ILoginUserService loginUserService;
	private IBillsService billsService;
	private IShopService shopService;
	/**
	 * 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入bills")
	@TenantIgnore
	public R<IPage<AppBillsVO>> list(Bills bills, Query query,String billType,String format) {
		QueryWrapper<Bills> queryWrapper = new QueryWrapper();
		if(StringUtils.isEmpty(format) && ObjectUtils.isNotEmpty(bills.getCreateTime())){
			format = DateUtil.format(bills.getCreateTime(),"yyyy-MM");
		}
		queryWrapper.lambda()
			.eq(bills.getReceiveId()!=null,Bills::getReceiveId,bills.getReceiveId())
			.eq(bills.getPayId()!=null,Bills::getPayId,bills.getPayId())
			.gt("price".equals(billType),Bills::getPrice, BigDecimal.ZERO)
			.gt("balanceNum".equals(billType),Bills::getBalanceNum, BigDecimal.ZERO)
			.gt("pointNum".equals(billType),Bills::getPointNum, BigDecimal.ZERO)
			.likeRight(format!=null,Bills::getCreateTime,format)
			.and(wrapper ->wrapper.eq(Bills::getPayStatus,AppConstant.BillPayStatus.付款成功.name()).or().eq(Bills::getCsFlag, CsFlag.CHECK))
			.orderByDesc(Bills::getCreateTime);
		IPage<Bills> pages = billsService.page(Condition.getPage(query), queryWrapper);
		return R.data(AppBillsWrapper.build(loginUserService).pageVO(pages));
	}

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入bills")
	@TenantIgnore
	public R<AppBillsVO> detail(Bills bills) {
		Bills detail = billsService.getOne(Condition.getQueryWrapper(bills));
		return R.data(AppBillsWrapper.build(loginUserService).entityVO(detail));
	}

	/**
	 * 我的账单【c端】
	 */
	@GetMapping("/myBills")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "我的账单", notes = "传入bills")
	public R<IPage<AppBillsVO>> myBills(Bills bills, Query query ,String yearMoth) {
		String format = null;
		if (bills.getCreateTime() != null) {
			//筛选年
			format = DateUtil.format(bills.getCreateTime(), "yyyy");
			bills.setCreateTime(null);
		}

		if (StrUtil.isNotBlank(yearMoth)) {
			//筛选年月
			format = DateUtil.format(bills.getCreateTime(),"yyyy-MM");
		}
		QueryWrapper<Bills> queryWrapper = new QueryWrapper();
		queryWrapper.lambda()
			.eq(Bills::getPayId,bills.getPayId())
			.like(format!=null,Bills::getCreateTime,format)
			.and(wrapper ->wrapper.eq(Bills::getPayStatus,AppConstant.BillPayStatus.付款成功.name()).or().eq(Bills::getCsFlag,CsFlag.CHECK))
			.orderByDesc(Bills::getCreateTime);
		IPage<Bills> pages = billsService.page(Condition.getPage(query), queryWrapper);
		return R.data(AppBillsWrapper.build(shopService).pageVO(pages));
	}



	@GetMapping("/getBillStatistics")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "获取统计数据", notes = "传入billStatisticsDTO")
	public R getBillStatistics(BillStatisticsDTO billStatisticsDTO) {

		Assert.notNull(billStatisticsDTO.getQueryDate(), "查询日期不能为空");
		String year = DateUtil.format(billStatisticsDTO.getQueryDate(), "YYYY");

		//获取统计数据
		int count = billsService.count(Condition.getQueryWrapper(new Bills()).lambda()
			.eq(billStatisticsDTO.getPayId() != null, Bills::getPayId, billStatisticsDTO.getPayId())
			.eq(billStatisticsDTO.getReceiveId() != null, Bills::getReceiveId, billStatisticsDTO.getReceiveId())
			.between(Bills::getCreateTime, DateUtil.beginOfYear(billStatisticsDTO.getQueryDate()), DateUtil.endOfYear(billStatisticsDTO.getQueryDate()))
			.and(wrapper -> wrapper.eq(Bills::getPayStatus, AppConstant.BillPayStatus.付款成功.name()).or().eq(Bills::getCsFlag,CsFlag.CHECK)));

		//获取合计多少元
		QueryWrapper<Bills> billsQueryWrapper = Condition.getQueryWrapper(new Bills());
		billsQueryWrapper.select("SUM(" + billStatisticsDTO.getQueryColumn() + ") as totalMoney")
			.eq(billStatisticsDTO.getPayId() != null, "pay_id", billStatisticsDTO.getPayId())
			.eq(billStatisticsDTO.getReceiveId() != null, "receive_id", billStatisticsDTO.getReceiveId())
			.and(wrapper -> wrapper.eq("pay_status", AppConstant.BillPayStatus.付款成功.name()).or().eq("cs_flag",CsFlag.CHECK))
			.between("create_time", DateUtil.beginOfYear(billStatisticsDTO.getQueryDate()), DateUtil.endOfYear(billStatisticsDTO.getQueryDate()));
		Map<String, Object> map = billsService.getMap(billsQueryWrapper);
		BigDecimal totalMoney = BigDecimal.ZERO;
		if (MapUtil.isNotEmpty(map)) {
			totalMoney = Convert.toBigDecimal(map.get("totalMoney"));
		}
		//获取图表数据
		QueryWrapper<Bills> queryWrapper = Condition.getQueryWrapper(new Bills());
		queryWrapper.select("DATE_FORMAT(create_time, '%c') as month, sum("+billStatisticsDTO.getQueryColumn()+") as money")
			.eq("DATE_FORMAT(create_time, '%Y')", year)
			.eq(billStatisticsDTO.getPayId() != null, "pay_id", billStatisticsDTO.getPayId())
			.eq(billStatisticsDTO.getReceiveId() != null, "receive_id", billStatisticsDTO.getReceiveId())
			.and(wrapper -> wrapper.eq("pay_status", AppConstant.BillPayStatus.付款成功.name()).or().eq("cs_flag",CsFlag.CHECK))
			.groupBy("month");

		List<Map<String, Object>> listMaps = billsService.listMaps(queryWrapper);
		List<String> monthList = listMaps.stream().map(item -> Convert.toStr(item.get("month"))+"月").collect(Collectors.toList());
		List<BigDecimal> dataList = listMaps.stream().map(item -> Convert.toBigDecimal(item.get("money"))).collect(Collectors.toList());

		BillStatisticsVO statisticsVO = BillStatisticsVO.builder()
			.payNum(count)
			.totalMoney(totalMoney)
			.monthList(monthList)
			.dataList(dataList).build();
		return R.data(statisticsVO);
	}
}
