
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.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.sky.core.log.exception.ServiceException;
import org.sky.core.mp.base.BaseServiceImpl;
import org.sky.core.mp.support.Condition;
import org.sky.core.mp.support.Query;
import org.sky.core.secure.utils.SecureUtil;
import org.sky.core.tool.utils.*;
import org.sky.scientific.e.XmStatusEnum;
import org.sky.scientific.excel.XmExcel;
import org.sky.scientific.mapper.DepartmentMapper;
import org.sky.scientific.mapper.TechnicianMapper;
import org.sky.scientific.mapper.XmMapper;
import org.sky.scientific.pojo.dto.XmDTO;
import org.sky.scientific.pojo.dto.XmUpdateDto;
import org.sky.scientific.pojo.entity.XmEntity;
import org.sky.scientific.pojo.vo.XmSummary;
import org.sky.scientific.pojo.vo.XmVO;
import org.sky.scientific.pojo.vo.XmYszbVO;
import org.sky.scientific.service.IXmService;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 科研项目 服务实现类
 *
 * @author Kd
 * @since 2025-06-29
 */
@Service
@AllArgsConstructor
public class XmServiceImpl extends BaseServiceImpl<XmMapper, XmEntity> implements IXmService {

	private final TechnicianMapper technicianMapper;
	private final DepartmentMapper departmentMapper;

	@Override
	public IPage<XmEntity> selectXmList(IPage<XmEntity> page, XmDTO xm) {
		if (StringUtil.isBlank(xm.getYearAndMonth())) {
//			throw new ServiceException("参数yearAndMonth不能为空");
			xm.setYearAndMonth(DateUtil.format(new Date(), DateUtil.PATTERN_YYYYMM));
		}
		return page.setRecords(baseMapper.selectXmPage(page, xm));
	}

	@Override
	public List<XmEntity> selectXmListByYear(String year) {
		if (Func.isBlank(year)) {
			throw new ServiceException("参数year不能为空");
		}
		return baseMapper.selectXmListByYear(year);
	}

	@Override
	public List<XmExcel> exportXm(Wrapper<XmEntity> queryWrapper) {
		List<XmExcel> xmList = baseMapper.exportXm(queryWrapper);
		//xmList.forEach(xm -> {
		//	xm.setTypeName(DictCache.getValue(DictEnum.YES_NO, Xm.getType()));
		//});
		return xmList;
	}

	@Override
	public Long approval(XmDTO xm) {

		this.judgeXmmcAvailable(xm.getXmmc());

		//检查项目名称是否重复(xm);
		LambdaQueryWrapper<XmEntity> queryWrapper = Wrappers.<XmEntity>lambdaQuery().eq(XmEntity::getXmmc, xm.getXmmc());
		if (baseMapper.selectCount(queryWrapper) > 0) {
			throw new ServiceException("研发项目名称已存在");
		}

		queryWrapper = Wrappers.<XmEntity>lambdaQuery().eq(XmEntity::getXmbh, xm.getXmbh());
		if (baseMapper.selectCount(queryWrapper) > 0) {
			throw new ServiceException("研发项目编号已存在");
		}

		if (xm.getXmyszemx() != null) {
			List<JSONObject> list = JSONObject.parseArray(xm.getXmyszemx(), JSONObject.class);
			if (CollectionUtil.isNotEmpty(list)) {
				double total = list.stream().mapToDouble(t -> t.getDouble("amount")).sum();
				if (total != xm.getXmysze().doubleValue()) {
					throw new ServiceException("项目预算总额明细不对");
				}
			}
		}

		return this.save(xm) ? xm.getId() : null;
	}

	@Override
	public XmVO selectApprovalInfo(Long xmId) {
		XmEntity xm = baseMapper.selectById(xmId);
		xm.setXmfzrxm(technicianMapper.getNameById(xm.getXmfzr()));
		xm.setXmsqdw(departmentMapper.getFullNameById(xm.getXmsqdwid()));
		return BeanUtil.copyProperties(xm, XmVO.class);
	}

	@Override
	public boolean updateXm(XmUpdateDto dto) {
		return baseMapper.updateXm(dto);
	}

	@Override
	public IPage<XmSummary> summaryPage(IPage<XmSummary> page, XmDTO xm) {
		xm.setTenantId(SecureUtil.getTenantId());
		List<XmSummary> xmList = baseMapper.summaryPage(page, xm);

		int year = Integer.parseInt(xm.getYearAndMonth().substring(0, 4));
		for (XmSummary xmVO : xmList) {

			//立项报告数量
			xmVO.setLxbgCount(JSON.parseArray(xmVO.getLxbg()).size());

			List<JSONObject> xmysmx = JSON.parseArray(xmVO.getXmyszemx(), JSONObject.class);
			//预算总额
			xmVO.setXmysze(BigDecimal.valueOf(xmysmx.stream().mapToDouble(item -> JSONObject.parseObject(item.toString()).getDoubleValue("amount")).sum()));

			//本年度预算
			for (JSONObject o : xmysmx) {
				if (o.getInteger("year") == year) {
					xmVO.setXmyszeCurrentYear(o.getDouble("amount"));
					break;
				}
			}

			xmVO.setXmsqdw(departmentMapper.getFullNameById(xmVO.getXmsqdwid()));
		}
		return page.setRecords(xmList);
	}

	@SneakyThrows
	@Override
	public void exportSummary(HttpServletResponse response, XmDTO dto) {
//		try {
			InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/研发项目汇总表.xls");
			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("utf-8");
			response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("研发项目汇总表.xls", Charsets.UTF_8));

			Query query = new Query().setCurrent(1).setSize(Integer.MAX_VALUE);

			List<XmSummary> list = this.summaryPage(Condition.getPage(query), dto).getRecords();
			AtomicInteger index = new AtomicInteger();
			for (XmSummary summary : list) {
				summary.setXh(index.incrementAndGet());
				Optional<XmStatusEnum> first = Arrays.stream(XmStatusEnum.values()).filter(status -> status.getCode() == summary.getStatus()).findFirst();
				summary.setStatusName(first.isPresent()?first.get().getName():"");

				summary.setXmkssjStr(DateUtil.format(summary.getXmkssj(), DateUtil.PATTERN_DATE));
				summary.setXmjssjStr(DateUtil.format(summary.getXmjssj(), DateUtil.PATTERN_DATE));

				summary.setLxbgStatus((summary.getLxbgCount()>0)?"已提交":"未提交");
				summary.setJdxbgStatus((summary.getJdxbgCount()>0)?"已提交":"未提交");
				summary.setYsbgStatus((summary.getYsbgCount()>0)?"已提交":"未提交");
			}

			ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
				.withTemplate((templateFileName))
				.excelType(ExcelTypeEnum.XLS)
				.build();

			WriteSheet writeSheet = EasyExcel.writerSheet().build();
			//设置list集合数据
			excelWriter.fill(list, writeSheet);
			Map<String, Object> map = new HashMap<>();
			map.put("year", dto.getYearAndMonth().substring(0, 4));
			map.put("month", dto.getYearAndMonth().substring(4));
			excelWriter.fill(map, writeSheet);
			excelWriter.finish();
			if (templateFileName != null) {
				templateFileName.close();
			}
//		}catch (Exception e) {
//			throw new ServiceException("导出失败，" + e.getLocalizedMessage());
//			try {
//				response.getWriter().write("{\"code\":500,\"msg\":\"操作失败\"}");
//			} catch (IOException ex) {
//				throw new RuntimeException(ex);
//			}
//		}

	}

	@Override
	public XmYszbVO selectYszb(Long xmId) {
		if (xmId == null || xmId <= 0) {
			throw new ServiceException("参数xmId不能为空");
		}
		XmYszbVO vo = baseMapper.selectYszb(xmId);
 		List<JSONObject> mxList = JSON.parseArray(vo.getXmyszemx(), JSONObject.class);
		vo.setXmysze(mxList.stream().mapToDouble(t -> t.getDouble("amount")).sum());

		vo.setXmsqdw(departmentMapper.getFullNameById(vo.getXmsqdwid()));
		return vo;
	}

	@Override
	public XmVO selectByXmId(Long xmId) {
		XmVO xmVO = baseMapper.selectByXmId(xmId);
		xmVO.setXmfzrxm(technicianMapper.getNameById(xmVO.getXmfzr()));
		xmVO.setXmsqdw(departmentMapper.getFullNameById(xmVO.getXmsqdwid()));
		return xmVO;
	}

	@Override
	public IPage<JSONObject> selectAssistList(IPage<JSONObject> page, XmDTO xm) {
		if (StringUtil.isBlank(xm.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}

		return page.setRecords(baseMapper.selectAssistList(page, xm));
	}


	/**
	 * 判断项目名称是否有效
	 *
	 * @param xmmc
	 */
	private void judgeXmmcAvailable(String xmmc) {
		//技改、技术改造、推广、打样、翻新、产业化、生产线、改造、年产、示范
		List<String> errorWords = Arrays.asList("技改", "技术改造", "推广", "打样", "翻新", "产业化", "生产线", "改造", "年产", "示范");
		int index = -1;
		for (String errorWord : errorWords) {
			index = xmmc.indexOf(errorWord);
			break;
		}
		if (index != -1) {
			throw new ServiceException("研发项目名称，不符合统计部门的命名要求！");
		}
	}

}
