package com.qunzhixinxi.hnqz.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qunzhixinxi.hnqz.admin.entity.*;
import com.qunzhixinxi.hnqz.admin.service.SysFileService;
import com.qunzhixinxi.hnqz.admin.service.WmDaCustomerService;
import com.qunzhixinxi.hnqz.admin.service.WmDaCustomerStatisticsService;
import com.qunzhixinxi.hnqz.admin.util.OsEnvUtils;
import com.qunzhixinxi.hnqz.common.core.util.R;
import lombok.AllArgsConstructor;
import net.fenghaitao.AutoExcel;
import net.fenghaitao.parameters.TemplateExportPara;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author lixuesong
 * @date 2021年06月04日 16:39
 */
@Service
@AllArgsConstructor
public class WmDaCustomerStatisticsServiceImpl implements WmDaCustomerStatisticsService {

	/**
	 * gmv1以分为单位的部门
	 */
	private final List<String> gmv1InFenDeptNameList = new ArrayList<String>(){{
		add("问问风湿"); add("上海问云生物科技有限公司");
	}};

	private final WmDaCustomerService wmDaCustomerService;

	private final SysFileService sysFileService;

	/**
	 * 查询指定月的统计列表
	 *
	 * @param page
	 * @param daCustomer
	 * @param startMonth
	 * @param endMonth
	 * @return
	 */
	@Override
	public IPage<WmDaCustomer> listMultiMonthStatisticsPage(Page page, WmDaCustomer daCustomer, Integer startMonth, Integer endMonth) {
		// 当前年月和上一日
		String currentYear = String.valueOf(LocalDate.now().getYear());
		IPage<WmDaCustomer> pageResult = wmDaCustomerService.listCustomerWithGmvPage(page, daCustomer, currentYear, startMonth, endMonth);
		List<WmDaCustomer> records = pageResult.getRecords();

		for (WmDaCustomer wmDaCustomer : records) {
			Map<String, WmDaCustomerStatistics> entRes = new HashMap<>(1);
			// gmv数据
			List<WmDeptGmv> deptGmvList = wmDaCustomer.getDeptGmvList();
			if (CollectionUtil.isNotEmpty(deptGmvList)) {
				deptGmvList.stream().filter(wmDeptGmv -> {
					// 过滤，只取指定月份区间的数据
					int month = Integer.parseInt(wmDeptGmv.getMonth());
					return month >= startMonth && month <= endMonth;
				}).forEach(wmDeptGmv -> {
					// 封装GMV数据
					WmDaCustomerStatistics customerStatistics = new WmDaCustomerStatistics();
					// 如果企业的积分是以分为单位，则需要转换 '分'->'元'
					if (gmv1InFenDeptNameList.contains(wmDaCustomer.getCustomerName())) {
						customerStatistics.setGmv1(BigDecimal.valueOf(wmDeptGmv.getGmv1() * 1.0 / 100)
								.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					} else {
						customerStatistics.setGmv1(BigDecimal.valueOf(wmDeptGmv.getGmv1()));
					}
					customerStatistics.setGmv2(BigDecimal.valueOf(wmDeptGmv.getGmv2() * 1.0 / 100)
							.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					customerStatistics.setIncome(BigDecimal.valueOf(wmDeptGmv.getIncome() * 1.0 / 100)
							.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					entRes.put(wmDeptGmv.getMonth(), customerStatistics);
				});
				wmDaCustomer.setMultiGMVStatistics(entRes);
				wmDaCustomer.setDeptGmvList(null);
			}
		}

		return pageResult;
	}

	/**
	 * 查询指定月的统计列表
	 *
	 * @param daCustomer
	 * @param startMonth
	 * @param endMonth
	 * @return
	 */
	@Override
	public List<WmDaCustomer> listMultiMonthStatistics(WmDaCustomer daCustomer, Integer startMonth, Integer endMonth) {
		// 当前年月和上一日
		String currentYear = String.valueOf(LocalDate.now().getYear());
		List<WmDaCustomer> records = wmDaCustomerService.listCustomerWithGmv(daCustomer, currentYear, startMonth, endMonth);
		// 填充统计数据
		records.parallelStream().forEach(wmDaCustomer -> {
			Map<String, WmDaCustomerStatistics> entRes = new HashMap<>(1);
			// gmv数据
			List<WmDeptGmv> deptGmvList = wmDaCustomer.getDeptGmvList();
			if (CollectionUtil.isNotEmpty(deptGmvList)) {
				deptGmvList.forEach(wmDeptGmv -> {
					// 封装GMV数据
					WmDaCustomerStatistics customerStatistics = new WmDaCustomerStatistics();
					// 如果企业的积分是以分为单位，则需要转换 '分'->'元'
					if (gmv1InFenDeptNameList.contains(wmDaCustomer.getCustomerName())) {
						customerStatistics.setGmv1(BigDecimal.valueOf(wmDeptGmv.getGmv1() * 1.0 / 100)
								.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					} else {
						customerStatistics.setGmv1(BigDecimal.valueOf(wmDeptGmv.getGmv1()));
					}
					customerStatistics.setGmv2(BigDecimal.valueOf(wmDeptGmv.getGmv2() * 1.0 / 100)
							.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					customerStatistics.setIncome(BigDecimal.valueOf(wmDeptGmv.getIncome() * 1.0 / 100)
							.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					entRes.put(wmDeptGmv.getMonth(), customerStatistics);
				});
				wmDaCustomer.setMultiGMVStatistics(entRes);
			}
		});

		return records;
	}

	/**
	 * 导出统计数据
	 *
	 * @param customerList
	 * @return
	 */
	@Override
	public R exportMultiMonthStatistics(List<WmDaCustomer> customerList) throws IOException {
		// 列表实体对象转换
		List<WmDaCustomerExportValue> exportList = new ArrayList<>();
		List<WmDaCustomerExportHeader> hearderList = new ArrayList<>();
		this.convertCustomerToExportList(customerList, exportList);
		this.convertCustomerToHeaderList(customerList, hearderList);
		// 服务器excel文件路径
		String resourcePath = (String) OsEnvUtils.getEachEnvPaths().get("EXCEL_FILE_PATH");
		// 模板路径
		String templatePath = resourcePath  + "monthly_sales_report_template.xlsx";
		// 导出的文件名
		String fileName = "月度销售报表_" + System.currentTimeMillis();
		// 导出文件缓存路径
		String outputPath = resourcePath + "out/" + fileName + ".xlsx";
		// 配置对应excel名称管理器的数据源
		List<TemplateExportPara> paraList = new ArrayList<>();
		TemplateExportPara para1 = new TemplateExportPara("WmDaCustomerExportHeader", hearderList);
		paraList.add(para1);
		TemplateExportPara para2 = new TemplateExportPara("WmDaCustomerExport", exportList);
		paraList.add(para2);
		// 导出前手动处理
		Consumer<Workbook> actionAhead = workbook -> {
		};
		// 导出后手动处理
		Consumer<Workbook> actionBehind = workbook -> {
		};
		File templateFile = new File(templatePath);
		File tempFile = new File(outputPath);
		File parentFile = tempFile.getParentFile();
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		tempFile.createNewFile();
		AutoExcel.save(templateFile.getAbsolutePath(), tempFile.getAbsolutePath(), paraList, actionAhead, actionBehind);
		FileInputStream tempStream = new FileInputStream(tempFile);
		MultipartFile multipartFile = new MockMultipartFile(fileName, fileName + ".xlsx",
				"text/plain", IOUtils.toByteArray(tempStream));
		// 上传到文件服务
		R result = sysFileService.uploadFileAllUrlRealName(multipartFile);
		// 删除temp文件
		tempFile.delete();
		return result;
	}

	/**
	 * 把customerList列表转换为导出的列表exportList
	 *
	 * @param customerList
	 * @param exportList
	 */
	private void convertCustomerToExportList(List<WmDaCustomer> customerList, List<WmDaCustomerExportValue> exportList) {
		customerList.forEach(wmDaCustomer -> {
			WmDaCustomerExportValue export = new WmDaCustomerExportValue();
			export.setCustomerName(wmDaCustomer.getCustomerName());
			export.setCustomerType(wmDaCustomer.getCustomerType() == null ? "" : wmDaCustomer.getCustomerType().getName());
			export.setCustomerManager(wmDaCustomer.getCustomerManager());
			export.setChannelName(wmDaCustomer.getChannelName());
			Map<String, WmDaCustomerStatistics> statisticsMap = wmDaCustomer.getMultiGMVStatistics();
			// 获取统计到的月份
			List<String> monthList = statisticsMap.keySet().stream().sorted((o1, o2) -> {
				int o1Int = Integer.parseInt(o1);
				int o2Int = Integer.parseInt(o2);
				return o1Int - o2Int;
			}).collect(Collectors.toList());
			// 遍历，依次将每月数据赋值到指定字段
			for (int i = 0; i < monthList.size(); i++) {
				WmDaCustomerStatistics statistics = statisticsMap.get(monthList.get(i));
				// 增加千位分隔符
				DecimalFormat thousandsSeparatorFormat = new DecimalFormat(",###.##");
				String gmv1 = thousandsSeparatorFormat.format(statistics.getGmv1().doubleValue());
				String gmv2 = thousandsSeparatorFormat.format(statistics.getGmv2().doubleValue());
				String income = thousandsSeparatorFormat.format(statistics.getIncome().doubleValue());
				switch (i) {
					case 0:
						export.setJanGmv1(gmv1);
						export.setJanGmv2(gmv2);
						export.setJanIncome(income);
						break;
					case 1:
						export.setFebGmv1(gmv1);
						export.setFebGmv2(gmv2);
						export.setFebIncome(income);
						break;
					case 2:
						export.setMarGmv1(gmv1);
						export.setMarGmv2(gmv2);
						export.setMarIncome(income);
						break;
					case 3:
						export.setAprGmv1(gmv1);
						export.setAprGmv2(gmv2);
						export.setAprIncome(income);
						break;
					case 4:
						export.setMayGmv1(gmv1);
						export.setMayGmv2(gmv2);
						export.setMayIncome(income);
						break;
					case 5:
						export.setJunGmv1(gmv1);
						export.setJunGmv2(gmv2);
						export.setJunIncome(income);
						break;
					case 6:
						export.setJulGmv1(gmv1);
						export.setJulGmv2(gmv2);
						export.setJulIncome(income);
						break;
					case 7:
						export.setAugGmv1(gmv1);
						export.setAugGmv2(gmv2);
						export.setAugIncome(income);
						break;
					case 8:
						export.setSeptGmv1(gmv1);
						export.setSeptGmv2(gmv2);
						export.setSeptIncome(income);
						break;
					case 9:
						export.setOctGmv1(gmv1);
						export.setOctGmv2(gmv2);
						export.setOctIncome(income);
						break;
					case 10:
						export.setNovGmv1(gmv1);
						export.setNovGmv2(gmv2);
						export.setNovIncome(income);
						break;
					case 11:
						export.setDecGmv1(gmv1);
						export.setDecGmv2(gmv2);
						export.setDecIncome(income);
						break;
					default:
				}

			}
			exportList.add(export);
		});
	}

	/**
	 * 把customerList列表转换为导出的列表headerList
	 * @param customerList
	 * @param headerList
	 */
	private void convertCustomerToHeaderList(List<WmDaCustomer> customerList, List<WmDaCustomerExportHeader> headerList) {
		WmDaCustomer wmDaCustomer = customerList.get(0);
		WmDaCustomerExportHeader header = new WmDaCustomerExportHeader();
		Map<String, WmDaCustomerStatistics> statisticsMap = wmDaCustomer.getMultiGMVStatistics();
		// 获取统计到的月份
		List<String> monthList = statisticsMap.keySet().stream().sorted((o1, o2) -> {
			int o1Int = Integer.parseInt(o1);
			int o2Int = Integer.parseInt(o2);
			return o1Int - o2Int;
		}).collect(Collectors.toList());
		// 遍历，依次将每月数据赋值到指定字段
		for (int i = 0; i < monthList.size(); i++) {
			switch (i) {
				case 0:
					header.setCol1(monthList.get(i) + "月");
					header.setCol1GMV1("GMV1");
					header.setCol1GMV2("GMV2");
					header.setCol1Income("要易收益");
					break;
				case 1:
					header.setCol2(monthList.get(i) + "月");
					header.setCol2GMV1("GMV1");
					header.setCol2GMV2("GMV2");
					header.setCol2Income("要易收益");
					break;
				case 2:
					header.setCol3(monthList.get(i) + "月");
					header.setCol3GMV1("GMV1");
					header.setCol3GMV2("GMV2");
					header.setCol3Income("要易收益");
					break;
				case 3:
					header.setCol4(monthList.get(i) + "月");
					header.setCol4GMV1("GMV1");
					header.setCol4GMV2("GMV2");
					header.setCol4Income("要易收益");
					break;
				case 4:
					header.setCol5(monthList.get(i) + "月");
					header.setCol5GMV1("GMV1");
					header.setCol5GMV2("GMV2");
					header.setCol5Income("要易收益");
					break;
				case 5:
					header.setCol6(monthList.get(i) + "月");
					header.setCol6GMV1("GMV1");
					header.setCol6GMV2("GMV2");
					header.setCol6Income("要易收益");
					break;
				case 6:
					header.setCol7(monthList.get(i) + "月");
					header.setCol7GMV1("GMV1");
					header.setCol7GMV2("GMV2");
					header.setCol7Income("要易收益");
					break;
				case 7:
					header.setCol8(monthList.get(i) + "月");
					header.setCol8GMV1("GMV1");
					header.setCol8GMV2("GMV2");
					header.setCol8Income("要易收益");
					break;
				case 8:
					header.setCol9(monthList.get(i) + "月");
					header.setCol9GMV1("GMV1");
					header.setCol9GMV2("GMV2");
					header.setCol9Income("要易收益");
					break;
				case 9:
					header.setCol10(monthList.get(i) + "月");
					header.setCol10GMV1("GMV1");
					header.setCol10GMV2("GMV2");
					header.setCol10Income("要易收益");
					break;
				case 10:
					header.setCol11(monthList.get(i) + "月");
					header.setCol11GMV1("GMV1");
					header.setCol11GMV2("GMV2");
					header.setCol11Income("要易收益");
					break;
				case 11:
					header.setCol12(monthList.get(i) + "月");
					header.setCol12GMV1("GMV1");
					header.setCol12GMV2("GMV2");
					header.setCol12Income("要易收益");
					break;
				default:
			}

		}
		headerList.add(header);
	}
}
