package org.springblade.audit.controller;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.audit.dto.CwBalanceDetailDTO;
import org.springblade.audit.dto.CwFactIncomeDTO;
import org.springblade.audit.dto.StreamDTO;
import org.springblade.audit.entity.AuditStreamDetail;
import org.springblade.audit.entity.CwBalanceDetail;
import org.springblade.audit.entity.CwFactIncome;
import org.springblade.audit.entity.Stream;
import org.springblade.audit.enums.StreamEnum;
import org.springblade.audit.listener.CwBalanceDetailListener;
import org.springblade.audit.listener.CwFactIncomeListener;
import org.springblade.audit.listener.StreamListener;
import org.springblade.audit.service.IAuditStreamDetailService;
import org.springblade.audit.service.ICwBalanceDetailService;
import org.springblade.audit.service.ICwFactIncomeService;
import org.springblade.audit.service.IStreamService;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.system.client.UserClient;
import org.springblade.system.client.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zbc
 * @since 2022-02-10
 */

@RestController
@RequestMapping("/stream")
@Api(value = "暂估收入数据管理", tags = "暂估收入数据接口")
@Slf4j
public class StreamController {


	@Autowired
	private IStreamService streamService;

	@Autowired
	private ICwBalanceDetailService cwBalanceDetailService;

	@Autowired
	private ICwFactIncomeService cwFactIncomeService;

	@Autowired
	private IAuditStreamDetailService auditStreamDetailService;

	@Autowired
	private UserClient userClient;

	private static final Pattern MONEY_PATTERN = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");

	private static final Pattern ZZS = Pattern.compile("^\\d*[1-9]\\d*$");

	@Value("${blade.file.uploadPath}")
	private String picDir;


	@GetMapping("/getCode")
	@ApiOperation(value = "获取其他渠道结算报表分类code")
	public R getCode() {
		return R.data(StreamEnum.values());
	}


	@PostMapping("/entrance")
	@ApiOperation(value = "报表导入", notes = "报表导入")
	public R entrance(@RequestParam(required = true, name = "file") MultipartFile file,
					  @RequestParam(required = true, name = "excelCode") String excelCode
	) {
		if (file == null) {
			return R.fail("导入文件不能为空");
		}
		if (StringUtils.isBlank(excelCode)) {
			return R.fail("excelCode不能为空");
		}
		//暂估收入 stream
		if (StreamEnum.STREAM.getCode().equals(excelCode)) {
			return StreamImport(file, excelCode);
		}
		//BalanceDetail(PRM发布--其他渠道结算)
		if (StreamEnum.CW_BALANCE_DETAIL.getCode().equals(excelCode)) {
			return CwBalanceDetailImport(file, excelCode);
		}
		//实收报表 (其他渠道结算)
		if (StreamEnum.CW_FACT_INCOME.getCode().equals(excelCode)) {
			return CwFactIncomeImport(file, excelCode);
		}
		return R.fail("excelCode 参数异常");
	}


	/**
	 * 实收报表 (其他渠道结算)
	 * @param file
	 * @param excelCode
	 * @return
	 */
	private R CwFactIncomeImport(MultipartFile file, String excelCode) {
		Long userId = SecureUtil.getUserId();
		String oFileName = file.getOriginalFilename();
		String fileSuffix = oFileName.substring(oFileName.lastIndexOf("."));
		if (
			!".xls".equalsIgnoreCase(fileSuffix) &&
				!".xlsx".equalsIgnoreCase(fileSuffix)
		) {
			return R.fail("只能上传xlsx/xls类型的文件");
		}

		String tempFileName = UUID.randomUUID().toString() + fileSuffix;
		File f = new File(picDir + excelCode + "/" + tempFileName);
		try {
			FileUtils.copyInputStreamToFile(file.getInputStream(), f);
		} catch (IOException e) {
			e.printStackTrace();
		}
		String path = "uploads/" + excelCode + "/"+ tempFileName;

		CwFactIncomeListener easyExcelListener = new CwFactIncomeListener();
		List<CwFactIncomeDTO> excelList = easyExcelListener.list;
//		User user = userService.getById(userId);
		UserModel user = userClient.getById(userId);

		try {
			InputStream inputStream = file.getInputStream();
			EasyExcel.read(inputStream, CwFactIncomeDTO.class, easyExcelListener).sheet().doRead();
			log.info("导入条数" + excelList.size());
			if(excelList.isEmpty() || excelList.size() < 1){
				return R.fail("没有可导入的数据");
			}

			List<CwFactIncome> voList = new ArrayList<CwFactIncome>();
			for (CwFactIncomeDTO obj : excelList) {
				try {
					/*if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(obj.getProvince()) || com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(obj.getSpname())){
						continue;
					}*/
					CwFactIncome bean = new CwFactIncome();
					BeanUtils.copyProperties(obj, bean);
					if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getThemonth())){
						bean.setThemonth(Long.valueOf(obj.getThemonth().replaceAll(",", "")));
					}
					//实收信息费_元
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getFactIncome())) {
						bean.setFactIncome(new BigDecimal(obj.getFactIncome().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//订购量
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getOrders())) {
						bean.setOrders(new BigDecimal(obj.getOrders().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					voList.add(bean);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			String theMonth = voList.get(0).getThemonth().toString();
			//去除同月份数据
			cwFactIncomeService.remove(new LambdaQueryWrapper<CwFactIncome>()
				.eq(CwFactIncome::getThemonth,voList.get(0).getThemonth())
			);

			boolean sa = cwFactIncomeService.saveBatch(voList);
			if(sa){
				//spid赋值
				cwFactIncomeService.giveSpidSoul(theMonth);
				log.info("spid赋值 处理完成");
				//spid赋值2
				cwFactIncomeService.giveSpidSoulTwo(theMonth);
				log.info("spid赋值2 处理完成");
				//spid赋值3
				cwFactIncomeService.giveSpidSoulThree(theMonth);
				log.info("spid赋值3 处理完成");

				AuditStreamDetail entity = new AuditStreamDetail();
				entity.setCategoryCode(excelCode);
				entity.setReportName(file.getOriginalFilename());
				entity.setCreateUser(user.getName());
				entity.setReportUrl(path);
				entity.setCreateTime(new Date());
				boolean save = auditStreamDetailService.save(entity);
				log.info("导入记录保存完成 === {}",save);
				return R.success("导入成功");
			}
			return R.fail("导入失败");
		} catch (Exception e) {
			e.printStackTrace();
			return R.fail("数据处理异常");
		}
	}





	/**
	 * BalanceDetail(PRM发布--其他渠道结算)
	 * @param file
	 * @param excelCode
	 * @return
	 */
	private R CwBalanceDetailImport(MultipartFile file, String excelCode) {
		Long userId = SecureUtil.getUserId();
		String oFileName = file.getOriginalFilename();
		String fileSuffix = oFileName.substring(oFileName.lastIndexOf("."));
		if (
			!".xls".equalsIgnoreCase(fileSuffix) &&
				!".xlsx".equalsIgnoreCase(fileSuffix)
		) {
			return R.fail("只能上传xlsx/xls类型的文件");
		}

		log.info("BalanceDetail(PRM发布--其他渠道结算) 导入校验");
		String theCode = "";
		String theMonth = "";
		try {
			String excelName = oFileName.substring(0,oFileName.lastIndexOf("."));
			String code = excelName.replaceAll("\\s*", "");
			String substring = code.substring(code.length() - 11, code.length());
			String month = substring.substring(0, 6);
			String spCode = substring.substring(6, substring.length());
			theCode = spCode;
			theMonth = month;
			log.info("theCode = {},theMonth = {}",code,month);
		}catch (Exception e){
			e.printStackTrace();
			return R.fail("报表名不符合导入要求");
		}

		String tempFileName = UUID.randomUUID().toString() + fileSuffix;
		File f = new File(picDir + excelCode + "/" + tempFileName);
		try {
			FileUtils.copyInputStreamToFile(file.getInputStream(), f);
		} catch (IOException e) {
			e.printStackTrace();
		}
		String path = "uploads/" + excelCode + "/"+ tempFileName;


		CwBalanceDetailListener easyExcelListener = new CwBalanceDetailListener();
		List<CwBalanceDetailDTO> excelList = easyExcelListener.list;
//		User user = userService.getById(userId);
		UserModel user = userClient.getById(userId);

		try {
			InputStream inputStream = file.getInputStream();
			EasyExcel.read(inputStream, CwBalanceDetailDTO.class, easyExcelListener).sheet().doRead();
			log.info("导入条数" + excelList.size());
			if(excelList.isEmpty() || excelList.size() < 1){
				return R.fail("没有可导入的数据");
			}

			List<CwBalanceDetail> voList = new ArrayList<CwBalanceDetail>();
			for (CwBalanceDetailDTO obj : excelList) {
				try {
					/*if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(obj.getProvince()) || com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(obj.getSpname())){
						continue;
					}*/
					CwBalanceDetail bean = new CwBalanceDetail();
					BeanUtils.copyProperties(obj, bean);
					bean.setThemonth(Long.valueOf(theMonth));
					bean.setSpcode(theCode);
					//客服退赔付费(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getMoney1())) {
						bean.setMoney1(new BigDecimal(obj.getMoney1().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//省分违约扣款(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getMoney2())) {
						bean.setMoney2(new BigDecimal(obj.getMoney2().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//调帐金额(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getMoney3())) {
						bean.setMoney3(new BigDecimal(obj.getMoney3().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//不规范定制处罚费（元）
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getMoney4())) {
						bean.setMoney4(new BigDecimal(obj.getMoney4().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}

					//应收信息费(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getFee1())) {
						bean.setFee1(new BigDecimal(obj.getFee1().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//省分实收信息费(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getFee2())) {
						bean.setFee2(new BigDecimal(obj.getFee2().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//实际结算金额(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getFee3())) {
						bean.setFee3(new BigDecimal(obj.getFee3().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}


					//剔除话单总额(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getDiscount1())) {
						bean.setDiscount1(new BigDecimal(obj.getDiscount1().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//欠费总额(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getArrearage())) {
						bean.setArrearage(new BigDecimal(obj.getArrearage().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//20条扣款总额(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getDiscount20())) {
						bean.setDiscount20(new BigDecimal(obj.getDiscount20().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					//不均衡通信费(元)
					if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(obj.getImbalance())) {
						bean.setImbalance(new BigDecimal(obj.getImbalance().replaceAll(",", "")).setScale(2, BigDecimal.ROUND_HALF_UP));
					}
					voList.add(bean);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			//去除同月份数据
			cwBalanceDetailService.remove(new LambdaQueryWrapper<CwBalanceDetail>()
				.eq(CwBalanceDetail::getSpcode,theCode)
				.eq(CwBalanceDetail::getThemonth,theMonth)
			);

			boolean sa = cwBalanceDetailService.saveBatch(voList);
			if(sa){
				//spid赋值
				cwBalanceDetailService.giveSpidSoul(theMonth);
				log.info("spid赋值 处理完成");
				//spid赋值2
				cwBalanceDetailService.giveSpidSoulTwo(theMonth);
				log.info("spid赋值2 处理完成");

				AuditStreamDetail entity = new AuditStreamDetail();
				entity.setCategoryCode(excelCode);
				entity.setReportName(file.getOriginalFilename());
				entity.setCreateUser(user.getName());
				entity.setReportUrl(path);
				entity.setCreateTime(new Date());
				boolean save = auditStreamDetailService.save(entity);
				log.info("导入记录保存完成 === {}",save);
				return R.success("导入成功");
			}
			return R.fail("导入失败");
		} catch (Exception e) {
			e.printStackTrace();
			return R.fail("数据处理异常");
		}
	}


	/**
	 * 暂估收入报表导入
	 * @param file
	 * @return
	 */
	private R StreamImport(MultipartFile file, String excelCode) {
		Long userId = SecureUtil.getUserId();
		String oFileName = file.getOriginalFilename();
		String fileSuffix = oFileName.substring(oFileName.lastIndexOf("."));
		if (
			!".xls".equalsIgnoreCase(fileSuffix) &&
			!".xlsx".equalsIgnoreCase(fileSuffix)
		) {
			return R.fail("只能上传xlsx/xls类型的文件");
		}
		String tempFileName = UUID.randomUUID().toString() + fileSuffix;
		File f = new File(picDir + tempFileName);
		try {
			FileUtils.copyInputStreamToFile(file.getInputStream(), f);
		} catch (IOException e) {
			e.printStackTrace();
		}
		String path = "uploads/" + tempFileName;

		StreamListener easyExcelListener = new StreamListener();
		List<StreamDTO> excelList = easyExcelListener.list;
		List <String> theMonth = easyExcelListener.theMonth;
//		User user = userService.getById(userId);
		UserModel user = userClient.getById(userId);
		try {
			InputStream inputStream = file.getInputStream();
			EasyExcel.read(inputStream, StreamDTO.class, easyExcelListener).sheet().doRead();
			log.info("导入条数" + excelList.size());
			if(excelList.isEmpty() || excelList.size() < 1){
				return R.fail("没有可导入的数据");
			}

			List<Stream> voList = new ArrayList<Stream>();
			SimpleDateFormat simple = new SimpleDateFormat("yyyyMM");
			Date parse = simple.parse(theMonth.get(0));
			Calendar cale = Calendar.getInstance();
			cale.setTime(parse);
			cale.add(Calendar.MONTH,-1);
			Date time = cale.getTime();
			String format = simple.format(time);

			if (excelList != null && !excelList.isEmpty()) {
				for (StreamDTO obj : excelList) {
					try {
						Stream bean = new Stream();
						BeanUtils.copyProperties(obj, bean);
						bean.setMonth(format);
						//省份应收
						if (StringUtils.isNotBlank(obj.getProvincecost())) {
							String money = obj.getProvincecost().replaceAll(",", "");
							bean.setProvincecost(Double.valueOf(money));
						}

						//订购量
						if (StringUtils.isNotBlank(obj.getOrdernum())) {
							String num = obj.getOrdernum().replaceAll(",", "");
							bean.setOrdernum(Long.valueOf(num));
						}

						//结算金额
						if (StringUtils.isNotBlank(obj.getAccoutcost())) {
							String money = obj.getAccoutcost().replaceAll(",", "");
							bean.setAccoutcost(Long.valueOf(money));
						}

						//退赔费
						if (StringUtils.isNotBlank(obj.getRecedecost())) {
							String money = obj.getRecedecost().replaceAll(",", "");
							bean.setRecedecost(Long.valueOf(money));
						}

						//不均衡通道费
						if (StringUtils.isNotBlank(obj.getChannelcost())) {
							String money = obj.getChannelcost().replaceAll(",", "");
							bean.setChannelcost(Long.valueOf(money));
						}

						//十二条费用
						if (StringUtils.isNotBlank(obj.getTwentycost())) {
							String money = obj.getTwentycost().replaceAll(",", "");
							bean.setTwentycost(Long.valueOf(money));
						}

						//调账金额
						if (StringUtils.isNotBlank(obj.getTruncost())) {
							String money = obj.getTruncost().replaceAll(",", "");
							bean.setTruncost(Long.valueOf(money));
						}

						//违约扣款金额
						if (StringUtils.isNotBlank(obj.getBreakcost())) {
							String money = obj.getBreakcost().replaceAll(",", "");
							bean.setBreakcost(Long.valueOf(money));
						}
						voList.add(bean);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			//清空临时表
			streamService.remove(new LambdaQueryWrapper<Stream>()
				.eq(Stream::getMonth,format)
			);

			boolean fct = streamService.saveBatch(voList);

			//删除总计行
			streamService.remove(new LambdaQueryWrapper<Stream>()
				.eq(Stream::getMonth,format)
				.isNull(Stream::getServiceid)
			);
			if(fct){
				AuditStreamDetail entity = new AuditStreamDetail();
				entity.setCategoryCode(excelCode);
				entity.setReportName(file.getOriginalFilename());
				entity.setCreateUser(user.getName());
				entity.setReportUrl(path);
				entity.setCreateTime(new Date());
				boolean save = auditStreamDetailService.save(entity);
				log.info("导入记录保存完成 === {}",save);
				return R.success("导入成功");
			}
			return R.fail("导入失败");
		} catch (Exception e) {
			e.printStackTrace();
			return R.fail("导入失败");
		}
	}

	private Date sysDate(String time) {
		SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date parse = simple.parse(time);
			return parse;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}


}

