/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.salary.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.OSSUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.FileVo;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAtta;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.TSalaryAttaMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAccountService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAttaService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryStandardService;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryAttaVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryAccountExportByEkpVo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 薪资结算附件表
 *
 * @author hgw
 * @date 2022-08-05 11:40:14
 */
@Log4j2
@Service
@AllArgsConstructor
public class TSalaryAttaServiceImpl extends ServiceImpl<TSalaryAttaMapper, TSalaryAtta> implements TSalaryAttaService {

	private final OSSUtil ossUtil;

	private final TSalaryStandardService tSalaryStandardService;
	private final TSalaryAccountService tSalaryAccountService;

	/**
	 * 薪资结算附件表简单分页查询
	 *
	 * @param tAtta 薪资结算附件表
	 * @return
	 */
	@Override
	public IPage<TSalaryAtta> getTAttaPage(Page<TSalaryAtta> page, TSalaryAtta tAtta) {
		return baseMapper.getTAttaPage(page, tAtta);
	}

	/**
	 * @Description: 工程薪资暂停发附件上传
	 * @Author: hgw
	 * @Date: 2021/10/27 15:43
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> uploadEngineerPauseSalaryAtta(MultipartFile[] file, String filePath, String linkId, Integer linkType
			, Integer[] engineerType, String recordId) throws IOException {
		if (Common.isEmpty(file) || Common.isEmpty(engineerType) || engineerType.length != file.length) {
			return R.failed(CommonConstants.PARAM_INFO_ERROR);
		}
		for (int i = 0; i < file.length; i++) {
			this.uploadAtta(file[i], filePath, linkId, linkType, engineerType[i], null, recordId);
		}
		return R.ok("上传成功！");
	}

	/**
	 * @Description: 自定义暂停发附件上传
	 * @Author: hgw
	 * @Date: 2021-11-22 17:37:39
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> uploadPauseDiyAtta(MultipartFile[] file, String filePath, String linkId, Integer linkType
			, String recordId) throws IOException {
		if (Common.isEmpty(file)) {
			return R.failed(CommonConstants.PARAM_INFO_ERROR);
		}
		for (int i = 0; i < file.length; i++) {
			this.uploadAtta(file[i], filePath, linkId, linkType, null, null, recordId);
		}
		return R.ok("上传成功！");
	}

	/**
	 * @Description: 自定义暂停发附件上传
	 * @Author: hgw
	 * @Date: 2021-11-22 17:37:39
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> uploadLostAndFoundAtta(MultipartFile[] file, String filePath, String linkId, Integer linkType) throws IOException {
		if (Common.isEmpty(file)) {
			return R.failed(CommonConstants.PARAM_INFO_ERROR);
		}
		for (int i = 0; i < file.length; i++) {
			this.uploadAtta(file[i], filePath, linkId, linkType, null, null, null);
		}
		return R.ok("上传成功！");
	}

	@Override
	public R<FileVo> uploadAtta(@RequestBody MultipartFile file, String filePath, String linkId
			, Integer linkType, Integer engineerType, String printRemark, String recordId) throws IOException {
		String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
		//filePath不传默认存储空间的根目录
		//jpg,jpeg,png,bmp
		String key = "";
		if (!Common.isNotNull(filePath)) {
			key = fileName;
		} else {
			key = filePath + "/" + fileName;
		}
		boolean flag = ossUtil.uploadFileByStream(file.getInputStream(), key, null);
		FileVo fileVo;
		TSalaryAtta salaryAtta;
		URL url = null;
		if (flag) {
			log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
			salaryAtta = this.saveTSalaryAtta(fileName, key, file.getSize(), linkId, linkType, engineerType, printRemark, recordId);
			try {
				this.save(salaryAtta);
			} catch (Exception e) {
				log.error("OSS文件上传接口异常：" + e.getMessage());
				ossUtil.deleteObject(null, key);
				return R.failed("failed:" + e.getMessage());
			}
			url = ossUtil.getObjectUrl(null, salaryAtta.getAttaSrc());
			fileVo = new FileVo(salaryAtta.getId(), salaryAtta.getAttaName(), url.toString());
			return R.ok(fileVo);
		} else {
			return R.failed("failed:上传至存储空间失败");
		}
	}

	/**
	 * @param fileName 文件名
	 * @param key      路径
	 * @param fileSize 大小
	 * @Description: 保存附件信息
	 * @Author: hgw
	 * @Date: 2019/10/25 15:49
	 * @return: com.yifu.cloud.v1.hrms.api.entity.TSalaryAtta
	 **/
	private TSalaryAtta saveTSalaryAtta(String fileName, String key, Long fileSize, String linkId
			, Integer linkType, Integer engineerType, String printRemark, String recordId) {
		TSalaryAtta salaryAtta = new TSalaryAtta();
		char slash = '/';
		char point = '.';
		if (fileName.lastIndexOf(slash) >= 0) {
			salaryAtta.setAttaName(key.substring(fileName.lastIndexOf(slash), fileName.length()));
		} else {
			salaryAtta.setAttaName(fileName);
		}
		salaryAtta.setAttaSize(fileSize);
		salaryAtta.setAttaSrc(key);
		if (key.lastIndexOf(point) >= 0) {
			salaryAtta.setAttaType(key.substring(fileName.lastIndexOf(point), fileName.length()));
		}
		salaryAtta.setAttaUrl("");
		salaryAtta.setCreateTime(LocalDateTime.now());
		salaryAtta.setUpdateTime(LocalDateTime.now());
		YifuUser user = SecurityUtils.getUser();
		salaryAtta.setCreateBy(null == user ? "" : user.getId());
		salaryAtta.setUpdateBy(null == user ? "" : user.getId());
		salaryAtta.setLinkId(linkId);
		salaryAtta.setLinkType(linkType);
		salaryAtta.setEngineerType(engineerType);
		salaryAtta.setPrintRemark(printRemark);
		salaryAtta.setRecordId(recordId);
		salaryAtta.setRecordStatus(CommonConstants.ZERO_INT);
		return salaryAtta;
	}

	/**
	 * @param linkId
	 * @param linkType
	 * @Description: 获取list，并且从oss服务器根据AttaSrc获取路径，塞入AttaUrl
	 * @Author: hgw
	 * @Date: 2021/11/19 16:03
	 * @return: java.util.List<com.yifu.cloud.v1.hrms.api.entity.TSalaryAtta>
	 **/
	@Override
	public List<TSalaryAtta> getAttaListHaveSrc(String linkId, Integer linkType) {
		// 附件
		TSalaryAtta sa = new TSalaryAtta();
		sa.setLinkId(linkId);
		// 附件类型：0工资；1工程工资；2暂停发；3自定义项暂停发 8 自有员工校验附件
		sa.setLinkType(linkType);
		sa.setRecordStatus(0);
		List<TSalaryAtta> attaList = baseMapper.getTAttaList(sa);
		this.setSrc(attaList);
		return attaList;
	}

	/**
	 * @param recordId
	 * @Description: 获取list，并且从oss服务器根据AttaSrc获取路径，塞入AttaUrl
	 * @Author: hgw
	 * @Date: 2021/11/19 16:03
	 * @return: java.util.List<com.yifu.cloud.v1.hrms.api.entity.TSalaryAtta>
	 **/
	@Override
	public List<TSalaryAtta> getAttaListByRecordId(String recordId) {
		// 附件
		TSalaryAtta sa = new TSalaryAtta();
		sa.setRecordId(recordId);
		List<TSalaryAtta> attaList = baseMapper.getTAttaList(sa);
		this.setSrc(attaList);
		return attaList;
	}

	/**
	 * @param salaryAttaIds
	 * @param linkId
	 * @author fxj
	 * @date 2021-12-03
	 * @description 更新附件关联id
	 */
	@Transactional
	@Override
	public void updateAttaByLinkId(List<String> salaryAttaIds, String linkId) {
		if (Common.isNotNull(salaryAttaIds) && Common.isNotNull(linkId)) {
			List<TSalaryAtta> attaList = baseMapper.selectList(Wrappers
					.<TSalaryAtta>query().lambda().in(TSalaryAtta::getId, salaryAttaIds));
			if (Common.isNotNull(attaList)) {
				for (TSalaryAtta atta : attaList) {
					atta.setLinkId(linkId);
					baseMapper.updateById(atta);
				}
			}
		}
	}

	/**
	 * @param attaList
	 * @Description: 塞路径
	 * @Author: hgw
	 * @Date: 2021/11/23 17:37
	 * @return: void
	 **/
	@Override
	public void setSrc(List<TSalaryAtta> attaList) {
		if (attaList != null && !attaList.isEmpty()) {
			URL url;
			for (TSalaryAtta tsa : attaList) {
				if (Common.isNotNull(tsa.getAttaSrc())) {
					url = ossUtil.getObjectUrl(null, tsa.getAttaSrc());
					tsa.setAttaUrl(String.valueOf(url));
				}
			}
		}
	}

	/**
	 * @param applyNo
	 * @Description: 获取薪资报账，转化为excel，上传到系统，然后将附件名称与地址返回
	 * @Author: hgw
	 * @Date: 2024/4/18 17:05
	 * @return: com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryAttaVo
	 **/
	@Override
	public synchronized SalaryAttaVo getSalaryAccountToExcel(String applyNo) {
		SalaryAttaVo returnVo = new SalaryAttaVo();
		List<TSalaryAccountExportByEkpVo> accountList = tSalaryAccountService.getAccountListByApplyNo(applyNo);
		if (accountList != null) {
			String filePath = "salaryAccountFile";
			String fileName = "薪资报表"+ applyNo + DateUtil.getThisTime() + CommonConstants.XLSX;
			String key = filePath + "/" + fileName;
			EasyExcelFactory.write(filePath, TSalaryAccountExportByEkpVo.class).sheet("薪资报表生成").doWrite(accountList);
			try {
				File file = new File(filePath);
				InputStream inputStream = new FileInputStream(file);
				// 调用上传服务
				boolean flag = ossUtil.uploadFileByStream(inputStream, key,null);
				if (flag) {
					log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
					TSalaryAtta salaryAtta = this.saveTSalaryAtta(fileName, key, file.length(), applyNo, 14, null, null, null);
					try {
						this.save(salaryAtta);
					} catch (Exception e) {
						log.error("OSS文件上传接口异常：" + e.getMessage());
						ossUtil.deleteObject(null, key);
					}
					URL url = ossUtil.getObjectUrl(null, salaryAtta.getAttaSrc());
					returnVo.setAttaUrl(url.toString());
					returnVo.setAttaName(salaryAtta.getAttaName());
					return returnVo;
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				//删除临时文件
				try {
					org.apache.commons.io.FileUtils.forceDelete(new File(filePath));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return returnVo;
	}

}
