
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 jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.sky.core.log.exception.ServiceException;
import org.sky.core.mp.base.BaseServiceImpl;
import org.sky.core.tool.utils.Func;
import org.sky.scientific.mapper.XmFinanceMapper;
import org.sky.scientific.mapper.XmMapper;
import org.sky.scientific.pojo.entity.XmEntity;
import org.sky.scientific.pojo.entity.XmFinanceEntity;
import org.sky.scientific.service.IXmFinanceService;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 会计/加计扣除/高新-研发项目清单 服务实现类
 *
 * @author Kd
 * @since 2025-06-29
 */
@Slf4j
@Service
public class XmFinanceServiceImpl extends BaseServiceImpl<XmFinanceMapper, XmFinanceEntity> implements IXmFinanceService {

	@Resource
	private XmMapper xmMapper;

	@Override
	public List<XmFinanceEntity> selectXmFinanceList(XmFinanceEntity dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		if (dto.getType() == null || !Arrays.asList(1, 2, 3).contains(dto.getType())) {
			throw new ServiceException("参数type为空或者错误");
		}
		return baseMapper.selectXmFinanceList(dto);
	}

	@Override
	public boolean saveFinance(XmFinanceEntity entity) {
		if (Func.isBlank(entity.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		if (entity.getType() == null || !Arrays.asList(1, 2, 3).contains(entity.getType())) {
			throw new ServiceException("参数type为空或者错误");
		}

		List<XmFinanceEntity> list = new ArrayList<>();
		for (Long xmId : entity.getXmIdList()) {
			XmFinanceEntity finance = new XmFinanceEntity();
			finance.setYearAndMonth(entity.getYearAndMonth());
			finance.setXmId(xmId);
			finance.setType(entity.getType());
			list.add(finance);
		}
		return this.saveBatch(list);
	}

	@Override
	public boolean physicalDeleteByIds(List<Long> ids) {
		return baseMapper.physicalDeleteByIds(ids);
	}

	@Override
	public boolean fetchFinance(XmFinanceEntity entity) {
		if (Func.isBlank(entity.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		if (entity.getType() == null || !Arrays.asList(1, 2, 3).contains(entity.getType())) {
			throw new ServiceException("参数type为空或者错误");
		}
		//根据yearAndMonth查询年度项目
		List<XmEntity> xmListByYear = xmMapper.selectXmListByYear(entity.getYearAndMonth());
		if (Func.isEmpty(xmListByYear)) {
			throw new ServiceException(entity.getYearAndMonth() + "年度内无研发项目可引入");
		}
		//根据yearAndMonth和type查询已有项目
		List<XmFinanceEntity> dbXmFinanceList = baseMapper.selectXmFinanceList(entity);

		//年度研发项目
		List<Long> xmIdList = xmListByYear.stream().map(XmEntity::getId).toList();

		//已添加的研发项目
		List<Long> xmIdFinances = dbXmFinanceList.stream().map(XmFinanceEntity::getXmId).toList();
		if (Func.isEmpty(xmIdFinances)) {
			xmIdFinances = new ArrayList<>();
		}
		//去重,差集
		List<Long> finalXmIdFinances = xmIdFinances;
		List<Long> collect = xmIdList.stream().filter(item -> !finalXmIdFinances.contains(item)).toList();
		//保存
		if (Func.isEmpty(collect)) {
			throw new ServiceException("年度研发项目已全部引入");
		}
		List<XmFinanceEntity> insertList = new ArrayList<>();
		for (Long xmId : collect) {
			XmFinanceEntity dto = new XmFinanceEntity();
			dto.setYearAndMonth(entity.getYearAndMonth());
			dto.setType(entity.getType());
			dto.setXmId(xmId);
			insertList.add(dto);
		}
		return this.saveBatch(insertList);
	}

	@SneakyThrows
	@Override
	public void exportFinance(OutputStream os, XmFinanceEntity dto) {
		List<XmFinanceEntity> list = this.selectXmFinanceList(dto);
		AtomicInteger index = new AtomicInteger(1);

		list.forEach(temp -> {
			temp.setXh(index.getAndIncrement() + "");
		});

		String title = dto.getYearAndMonth() + "年会计-研发项目清单";
		//类型，1：会计，2：加计扣除，3：高新
		if (Func.equals(dto.getType(), 2)) {
			title = dto.getYearAndMonth() + "年加计扣除-研发项目清单";
		} else if (Func.equals(dto.getType(), 3)) {
			title = dto.getYearAndMonth() + "年高新-研发项目清单";
		}
		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("title", title);
		excelWriter.fill(map, writeSheet);
		excelWriter.finish();
		if (templateFileName != null) {
			templateFileName.close();
		}
	}
}
