
package org.sky.scientific.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.sky.core.excel.util.ExcelUtil;
import org.sky.core.log.exception.ServiceException;
import org.sky.core.mp.base.BaseServiceImpl;
import org.sky.core.tool.utils.DateUtil;
import org.sky.core.tool.utils.Func;
import org.sky.core.tool.utils.StringUtil;
import org.sky.scientific.excel.XmWwxmCostExcel;
import org.sky.scientific.mapper.XmMapper;
import org.sky.scientific.mapper.XmWwxmCostMapper;
import org.sky.scientific.mapper.XmWwxmMapper;
import org.sky.scientific.pojo.dto.XmWwxmCostQuery;
import org.sky.scientific.pojo.entity.XmWwxmCost;
import org.sky.scientific.pojo.entity.XmWwxmEntity;
import org.sky.scientific.pojo.vo.XmWwxmCostVO;
import org.sky.scientific.service.IXmService;
import org.sky.scientific.service.IXmWwxmCostService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 委托外部研发费用-基本信息台账 服务实现类
 *
 * @author Kd
 * @since 2025-06-29
 */
@Service
@AllArgsConstructor
public class XmWwxmCostServiceImpl extends BaseServiceImpl<XmWwxmCostMapper, XmWwxmCost> implements IXmWwxmCostService {

	private final XmMapper xmMapper;
	private final XmWwxmMapper wwxmMapper;
	private final IXmService xmService;

	@Override
	@Transactional
	public boolean submit(XmWwxmCost cost) {

		String judged = DateUtil.judgeDate(cost.getPayDate(), cost.getYearAndMonth());
		if (judged != null) {
			throw new ServiceException(judged);
		}
		XmWwxmEntity wwxm = wwxmMapper.selectById(cost.getWwId());
		if (Func.notNull(wwxm)) {
			xmService.judgeXmIsOver(wwxm.getXmId(), true);
		}
		boolean result = false;
		if (Func.isNull(cost.getId())) {
			result = this.save(cost);
		} else {
			result = this.updateById(cost);
		}
		return result;
	}

	@Override
	public void importWwxmCost(MultipartFile file, String yearAndMonth) {
		if (Func.isBlank(yearAndMonth)) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		List<XmWwxmCostExcel> dataList = ExcelUtil.read(file, 0, 2, XmWwxmCostExcel.class);
		List<XmWwxmCost> insertList = new ArrayList<>();
		int batchCount = 20;
		for (XmWwxmCostExcel data : dataList) {
			String judged = DateUtil.judgeDate(data.getPayDate(), yearAndMonth);
			if (judged != null) {
				throw new ServiceException(judged);
			}

			if (StringUtil.isBlank(data.getXmbh())) {
				throw new ServiceException("序号为[" + data.getSerialNumber() + "]的项目研发编号和为空");
			}
			Long xmId = xmMapper.getXmIdByXmmcOrXmbh(null, null, data.getXmbh());
			if (xmId == null) {
				throw new ServiceException("序号为[" + data.getSerialNumber() + "]的项目不存在");
			}
			xmService.judgeXmIsOver(xmId, true);

			LambdaQueryWrapper<XmWwxmEntity> eq = Wrappers.<XmWwxmEntity>lambdaQuery()
				.eq(XmWwxmEntity::getXmId, xmId)
				.eq(XmWwxmEntity::getYearAndMonth, yearAndMonth.substring(0, 4))
				.eq(XmWwxmEntity::getStfqc, data.getStfqc());
			XmWwxmEntity wwxm = wwxmMapper.selectOne(eq);
			if (Func.isNull(wwxm)) {
				throw new ServiceException("序号[" + data.getSerialNumber() + "]的数据有误");
			}

			XmWwxmCost cost = new XmWwxmCost();
			cost.setWwId(wwxm.getId());
			cost.setPayDate(data.getPayDate());
			cost.setPayAmount(data.getPayAmount());
			cost.setYearAndMonth(yearAndMonth);
			insertList.add(cost);

			if (insertList.size() % batchCount == 0) {
				if (this.saveBatch(insertList)) insertList.clear();
			}
		}
		if (!Func.isEmpty(insertList)) {
			this.saveBatch(insertList);
		}
	}

	@Override
	@Transactional
	public boolean physicalDeleteByIds(List<Long> ids) {
		for (Long id : ids) {
			XmWwxmCost cost = baseMapper.selectById(id);
			if (Func.notNull(cost)) {
				XmWwxmEntity wwxm = wwxmMapper.selectById(cost.getWwId());
				if (Func.notNull(wwxm)) {
					xmService.judgeXmIsOver(wwxm.getXmId(), true);
				}
			}
		}
		return baseMapper.physicalDeleteByIds(ids);
	}

	@Override
	public IPage<XmWwxmCostVO> selectPage(IPage<XmWwxmCostVO> page, XmWwxmCostQuery dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		List<XmWwxmCostVO> list = null;
		if (dto.getYearAndMonth().length() == 6) {
			list = baseMapper.selectPageByYearAndMonth(page, dto);
		} else if (dto.getYearAndMonth().length() == 4) {
			list = baseMapper.selectPageByYear(page, dto);
		} else {
			throw new ServiceException("参数yearAndMonth格式错误，yyyyMM或yyyy");
		}
		return page.setRecords(list);
	}

	@SneakyThrows
	@Override
	public void export(OutputStream os, List<XmWwxmCostVO> list, String yearAndMonth) {
		AtomicInteger index = new AtomicInteger(1);
		list.forEach(temp -> {
			temp.setXh(index.getAndIncrement() + "");
			temp.setPayDateStr(Func.notNull(temp.getPayDate()) ? DateUtil.format(temp.getPayDate(), DateUtil.PATTERN_DATE) : null);

		});
		InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/研发费用管理/委托外部研究开发费用/研发费用管理-委托外部研究开发费用.xls");
		ExcelWriter excelWriter = EasyExcel.write(os)
			.withTemplate((templateFileName))
			.excelType(ExcelTypeEnum.XLS)
			.build();

		WriteSheet writeSheet = EasyExcel.writerSheet().build();
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
		//设置list集合数据
		excelWriter.fill(list, fillConfig, writeSheet);
		Map<String, Object> map = new HashMap<>();
		map.put("yearAndMonth", yearAndMonth.length() == 6 ? yearAndMonth.substring(0, 4) + "年" + yearAndMonth.substring(4) + "月" : yearAndMonth + "年");
		excelWriter.fill(map, writeSheet);
		excelWriter.finish();
		if (templateFileName != null) {
			templateFileName.close();
		}
	}
}
