/*
 *      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.ordercommission.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSON;
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.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springblade.common.constant.SystemConstant;
import org.springblade.common.utils.DateUtil;
import org.springblade.common.utils.Excelutil;
import org.springblade.common.utils.FileUtil;
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.Func;
import org.springblade.modules.guosen.agenter.service.IAgenterService;
import org.springblade.modules.guosen.ordercommission.dto.OrderCommissionDTO;
import org.springblade.modules.guosen.ordercommission.vo.OrderCommissionStaticDetailVO;
import org.springblade.modules.guosen.ordercommission.vo.OrderCommissionStaticVO;
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.ordercommission.entity.OrderCommission;
import org.springblade.modules.guosen.ordercommission.vo.OrderCommissionVO;
import org.springblade.modules.guosen.ordercommission.wrapper.OrderCommissionWrapper;
import org.springblade.modules.guosen.ordercommission.service.IOrderCommissionService;
import org.springblade.core.boot.ctrl.BladeController;

import java.io.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 控制器
 *
 * @author BladeX
 * @since 2021-06-25
 */
@RestController
@AllArgsConstructor
@RequestMapping("cyzh-guosen/ordercommission")
@Api(value = "", tags = "接口")
public class OrderCommissionController extends BladeController {

	private final IOrderCommissionService orderCommissionService;
	private final IAgenterService agenterService;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入orderCommission")
	public R<OrderCommissionVO> detail(OrderCommission orderCommission) {
		OrderCommission detail = orderCommissionService.getOne(Condition.getQueryWrapper(orderCommission));
		return R.data(OrderCommissionWrapper.build().entityVO(detail));
	}

	/**
	 * 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入orderCommission")
	public R<IPage<OrderCommissionVO>> list(OrderCommission orderCommission, Query query) {

		IPage<OrderCommission> pages = orderCommissionService.page(Condition.getPage(query),
			Condition.getQueryWrapper(orderCommission));
		return R.data(OrderCommissionWrapper.build().pageVO(pages));
	}


	/**
	 * 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入orderCommission")
	public R<IPage<OrderCommissionVO>> page(OrderCommissionVO orderCommission, Query query) {
		BladeUser user = AuthUtil.getUser();//判断当前登录身份，如果是代理
		boolean isProxy = ("代理").equals(user.getRoleName());
		orderCommission.setIsProxy(isProxy);
		orderCommission.setPhone(user.getAccount());

		IPage<OrderCommissionVO> pages = orderCommissionService.selectOrderCommissionPage(Condition.getPage(query), orderCommission);
		return R.data(pages);
	}

	/**
	 * 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入orderCommission")
	public R save(@Valid @RequestBody OrderCommission orderCommission) {
		return R.status(orderCommissionService.save(orderCommission));
	}

	/**
	 * 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入orderCommission")
	public R update(@Valid @RequestBody OrderCommission orderCommission) {
		return R.status(orderCommissionService.updateById(orderCommission));
	}

	/**
	 * 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入orderCommission")
	public R submit(@Valid @RequestBody OrderCommission orderCommission) {
		return R.status(orderCommissionService.saveOrUpdate(orderCommission));
	}


	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(orderCommissionService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * 根据代理人id和时间查询数据列表或统计数据
	 */
	@PostMapping("/getByAgenterAndTime")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "根据代理人id和时间查询数据列表或统计数据", notes = "传入ids")
	public R<OrderCommissionStaticVO> getByAgenterAndTime(@RequestBody OrderCommissionDTO orderCommissionDTO) throws ParseException {
		Assert.notNull(orderCommissionDTO.getAgenterId(), "代理人id不能为空");
		Integer staticType = orderCommissionDTO.getStaticType();
		List<String> dateList = new ArrayList<>();
		List<BigDecimal> dataList = 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> orderCommissions = this.orderCommissionService.getBaseMapper().selectList(new QueryWrapper<>(new OrderCommission()).lambda()
				.like(OrderCommission::getCreateTime, date)
				.eq(orderCommissionDTO.getStatus() != null , OrderCommission::getStatus,orderCommissionDTO.getStatus())
				.eq(OrderCommission::getAgenterId,orderCommissionDTO.getAgenterId()));
			BigDecimal decimal = orderCommissions.stream().map(OrderCommission::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
			dataList.add(decimal);
		});

		OrderCommissionStaticVO orderCommissionStaticVO = new OrderCommissionStaticVO();
		orderCommissionStaticVO.setDateList(dateList);
		orderCommissionStaticVO.setDataList(dataList);
		return R.data(orderCommissionStaticVO);
	}


	/**
	 * 根据代理人id和时间查询分佣明细以及总金额
	 */
	@PostMapping("/getListDetailByAgenterAndTime")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "根据代理人id和时间查询分佣明细以及总金额", notes = "传入ids")
	public R<OrderCommissionStaticDetailVO> getListDetailByAgenterAndTime(@RequestBody OrderCommissionDTO orderCommissionDTO) throws ParseException {
		Assert.notNull(orderCommissionDTO.getAgenterId(), "代理人id不能为空");
		Integer staticType = orderCommissionDTO.getStaticType();
		List<String> dateList = new ArrayList<>();
		List<OrderCommission> orderCommissions = 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> subList = this.orderCommissionService.getBaseMapper().selectList(new QueryWrapper<>(new OrderCommission()).lambda()
				.like(OrderCommission::getCreateTime, date).eq(OrderCommission::getStatus, orderCommissionDTO.getStatus()));

			orderCommissions.addAll(subList);
		});

		OrderCommissionStaticDetailVO orderCommissionStaticDetailVO = new OrderCommissionStaticDetailVO();
		orderCommissionStaticDetailVO.setOrderCommissions(orderCommissions);
		orderCommissionStaticDetailVO.setTotal(orderCommissions.stream().map(OrderCommission::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add));
		return R.data(orderCommissionStaticDetailVO);
	}


	/**
	 * 分佣结算
	 */
	@PostMapping("/ordercommissionFinish")
	@ApiOperationSupport(order = 7)
	@ResponseBody
	@ApiOperation(value = "分佣结算", notes = "传入ids")
	public void ordercommissionFinish(@RequestParam String json, HttpServletResponse response)  {
		try{


		OrderCommissionStaticDetailVO orderCommissionStaticDetailVO = JSON.parseObject(json, OrderCommissionStaticDetailVO.class);
		Assert.isFalse(orderCommissionStaticDetailVO.getOrderCommissions().size() == 0,"没有可结算的记录");
		String filePath = System.currentTimeMillis() + "ordercommissioncleartemplate.xlsx";

		// 模板读取
		// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
		// {} 代表普通变量 {.} 代表是list的变量


		List<OrderCommission> clearList = orderCommissionStaticDetailVO.getOrderCommissions().stream().map(orderCommission -> {
			orderCommission.setStatus(SystemConstant.CommissionStatus.PAYED.getValue());
			if(orderCommissionService.updateById(orderCommission)){
				return orderCommission;
			}else{
				return null;
			}
		}).collect(Collectors.toList());


		//模板路径
		String Template = "ordercommissioncleartemplate.xlsx";
		//创建工作簿对象
		ExcelWriter workBook = EasyExcel.write(filePath, OrderCommission.class).withTemplate(Template).build();

		//创建sheet对象
		WriteSheet sheet = EasyExcel.writerSheet().build();
		FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();

		HashMap<String, Object> map = new HashMap<>();
		map.put("total",clearList.stream().map(OrderCommission::getAmt).reduce(BigDecimal.ZERO,BigDecimal::add));
		map.put("name", orderCommissionStaticDetailVO.getAgenter().getName());
		map.put("phone", orderCommissionStaticDetailVO.getAgenter().getUserPhone());
		map.put("level", orderCommissionStaticDetailVO.getAgenter().getLevel() == 1 ? "独家代理" : "战略合作伙伴");
		map.put("starttime", orderCommissionStaticDetailVO.getStartTime());
		map.put("endtime", orderCommissionStaticDetailVO.getEndTime());
		//多组填充
		workBook.fill(clearList, fillConfig, sheet);//这里加上换行，避免单组填充覆盖了多组填充的数据
		//单组填充
		workBook.fill(map, sheet);

		workBook.finish();
		response.setHeader("content-type", "application/octet-stream");
		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition", "attachment;filename=" + filePath);

		//读取文件
		InputStream in = new FileInputStream(filePath);
		OutputStream out = response.getOutputStream();

		//写文件
		int b;
		while ((b = in.read()) != -1) {
			out.write(b);
		}

		in.close();
		out.close();


		File dbfFile = new File(filePath);
		if (dbfFile.exists()) {
			dbfFile.delete();
		}
		}catch (Exception e){
			e.printStackTrace();
		}
	}


}
