package com.yifu.cloud.plus.v1.yifu.salary.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainListVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ExcelUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.entity.SysMessageSalary;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.SysMessageSalaryMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.SysMessageSalaryService;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SysMessageSalaryExportVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SysMessageSalarySearchVo;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 最低工资提醒-每月更新一次
 *
 * @author hgw
 * @date 2019-11-21 17:18:10
 */
@AllArgsConstructor
@Service("sysMessageSalaryService")
public class SysMessageSalaryServiceImpl extends ServiceImpl<SysMessageSalaryMapper, SysMessageSalary> implements SysMessageSalaryService {
	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;


    /**
     * 最低工资提醒-每月更新一次简单分页查询
     *
     * @param sysMessageSalary 最低工资提醒-每月更新一次
     * @return
     */
    @Override
    public IPage<SysMessageSalary> getSysMessageSalaryPage(Page<SysMessageSalary> page, SysMessageSalary sysMessageSalary) {
       // TODO  权限处理
		return baseMapper.getSysMessageSalaryPage(page, sysMessageSalary, null);
	}

    @Override
    public IPage<SysMessageSalary> getSysMessageSalaryHandlePage(Page<SysMessageSalary> page, SysMessageSalary sysMessageSalary) {
        return baseMapper.getSysMessageSalaryHandlePage(page, sysMessageSalary);
    }

    /**
     * @Author fxj
     * @Description 新增-普通工资
	 * 最低工资提醒（和档案属性在职状态和员工类型无关）：
	 *         1.执行时间：每月1号上午六点 salaryTask         createSysMessageSalary
	 *         2.判断逻辑：先上传上月（发送EKP时间对应的月份）数据，然后取值薪资合计-（薪资单状态发送成功）实发小于配置的最低工资
	 *         3.数据消失逻辑：当月不消失；次月定时任务执行的时候删除，重新计算生成
	 *         4.反馈：只能反馈创建人为自己的数据
	 *         5.导出：可选择/按查询条件/全量导出，导出字段为列表字段
     * @Date 18:19 2022/8/17
    **/
    @Transactional
    @Override
    public void insertSalaryBySettleMonth(String settleMonth) {
        List<SysMessageSalary> sysMessageSalaries = baseMapper.insertSalaryBySettleMonth(settleMonth);
        //获取单位名称
        Map<String, TSettleDomainSelectVo> settleDomainSelectVoMap = Maps.newHashMap();
		//结算主体
		R<TSettleDomainListVo> domainListVoR = archivesDaprUtil.selectAllSettleDomainSelectVos();
		if (Common.isNotNull(domainListVoR)
				&& Common.isNotNull(domainListVoR.getData())
				&& Common.isNotNull(domainListVoR.getData().getListSelectVO()))
			for (TSettleDomainSelectVo selectVo : domainListVoR.getData().getListSelectVO()) {
				settleDomainSelectVoMap.put(selectVo.getId(),selectVo);
			}
		TSettleDomainSelectVo selectVo;
		for (SysMessageSalary sysMessageSalary : sysMessageSalaries) {
			selectVo = settleDomainSelectVoMap.get(sysMessageSalary.getDepartId());
			if (Common.isNotNull(selectVo)){
				sysMessageSalary.setCustomerId(selectVo.getCustomerId());
				sysMessageSalary.setCustomerName(selectVo.getCustomerName());
			}
			this.save(sysMessageSalary);
        }
    }


    /**
     * @param settleMonth 结算月
     * @Description: 生成前，先删除老数据
     * @Author: hgw
     * @Date: 2019/11/21 17:28
     * @return: void
     **/
    @Override
    @Transactional
    public void deleteAllBySettleMonth(String settleMonth) {
        baseMapper.deleteAllBySettleMonth(settleMonth);
    }

	/**
	 * @Author fxj
	 * @Description 最低工资提醒导出
	 * @Date 18:12 2022/8/17
	**/
	@Override
	public void listExport(HttpServletResponse response, SysMessageSalarySearchVo searchVo) {
		String fileName = "最低工资提醒批量导出" + DateUtil.getThisTime() + CommonConstants.XLSX;
		//获取要导出的列表
		List<SysMessageSalaryExportVo> list = new ArrayList<>();
		List<String> settleDomainIds =null;
		List<String> ids = Common.getList(searchVo.getIds());
		String sql = null;
		int count = noPageCountDiy(searchVo,settleDomainIds,ids,sql);
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding(CommonConstants.UTF8);
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName  , CommonConstants.UTF8));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcel.write(out, SysMessageSalaryExportVo.class).build();
			int index = 0;
			if (count >  CommonConstants.ZERO_INT){
				WriteSheet writeSheet;
				ExcelUtil<SysMessageSalaryExportVo> util;
				for (int i = 0; i <= count; ) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = noPageDiy(searchVo,settleDomainIds,ids,sql);
					if (Common.isNotNull(list)){
						util = new ExcelUtil<>(SysMessageSalaryExportVo.class);
						for (SysMessageSalaryExportVo vo:list){
							util.convertEntity(vo,null,null,null);
						}
					}
					if (Common.isNotNull(list)){
						writeSheet = EasyExcel.writerSheet("消息提醒"+index).build();
						excelWriter.write(list,writeSheet);
						index++;
					}
					i = i + CommonConstants.EXCEL_EXPORT_LIMIT;
					if (Common.isNotNull(list)){
						list.clear();
					}
				}
			}else {
				WriteSheet writeSheet = EasyExcel.writerSheet("消息提醒"+index).build();
				excelWriter.write(list,writeSheet);
			}
			if (Common.isNotNull(list)){
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		}catch (Exception e){
			log.error("执行异常" ,e);
		}finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	private List<SysMessageSalaryExportVo> noPageDiy(SysMessageSalarySearchVo searchVo,
													 List<String> settleDomainIds,
													 List<String> ids,
													 String sql) {
		return baseMapper.noPageDiy(searchVo,settleDomainIds,ids,sql);
	}

	private int noPageCountDiy(SysMessageSalarySearchVo searchVo,
							   List<String> settleDomainIds,
							   List<String> ids,
							   String sql) {
		return baseMapper.noPageCountDiy(searchVo,settleDomainIds,ids,sql);
	}

	/**
	 * @Author fxj
	 * @Description 反馈信息
	 * @Date 17:23 2022/8/17
	 * @Param
	 * @return
	 **/
	@Override
	public R<String> feedback(Integer reasonType, String id, String feedBack) {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(user)){
			return R.failed(CommonConstants.USER_FAIL);
		}
		SysMessageSalary entity = baseMapper.selectById(id);
		if (Common.isEmpty(entity)){
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		if (!user.getId().equals(entity.getCreateBy())){
			return R.failed("允许创建人反馈信息！");
		}
		entity.setReasonType(reasonType);
		entity.setFeedBack(feedBack);
		int res  = baseMapper.updateById(entity);
		if (res == CommonConstants.ONE_INT_NEGATE){
			return R.failed(CommonConstants.SAVE_FAILED);
		}
		return R.ok(null,CommonConstants.SAVE_SUCCESS);
	}
}
