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

import cn.hutool.core.util.StrUtil;
import com.yifu.cloud.plus.v1.batch.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.batch.mapper.SysConfigLimitMapper;
import com.yifu.cloud.plus.v1.batch.service.FileUploadService;
import com.yifu.cloud.plus.v1.batch.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ResultConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@RequiredArgsConstructor
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {

	private final OSSUtil ossUtil;

	private final TAttaInfoService tAttaInfoService;

	private AtomicInteger atomicInteger = new AtomicInteger(0);
	//初始化附件上传队列上限值
	private int maxLimit = 1;

	private final SysConfigLimitMapper configLimitMapper;

	@Override
	public R<TAttaInfo> uploadFileReturnAtta(MultipartFile file, String filePath, String type, String domainId) throws IOException {
		return uploadFileReturnAtta(file, filePath, type, domainId, null);
	}

	@Override
	public R<TAttaInfo> uploadFileReturnAtta(MultipartFile file, String filePath, String type, String domainId, String taskId) throws IOException {
		// 从当前上下文获取用户信息
		YifuUser user = SecurityUtils.getUser();
		if (user != null) {
			return uploadFileReturnAtta(file, filePath, type, domainId, taskId, user.getId(), user.getNickname());
		} else {
			return uploadFileReturnAtta(file, filePath, type, domainId, taskId, null, null);
		}
	}

	@Override
	public R<TAttaInfo> uploadFileReturnAtta(MultipartFile file, String filePath, String type, String domainId, 
											  String taskId, String userId, String userName) throws IOException {
		if (null == file) {
			return R.failed("文件删除异常，请重新上传！");
		}
		String fileName = file.getOriginalFilename();
		if (fileName == null || Common.isEmpty(fileName)) {
			return R.failed("文件名不能为空！！");
		}
		if (fileName.length() > 100) {
			return R.failed("文件名不能超过100个字符！");
		}
		//filePath不传默认存储空间的根目录
		//jpg,jpeg,png,bmp
		String key = "";
		if (Common.isNotNull(filePath)) {
			key = filePath + "/" + fileName;
		} else {
			key = System.currentTimeMillis() + fileName;
		}
		if (!Common.checkFile(key)) {
			return R.failed("非法上传类型："+fileName);
		}
		//判断是否存在此文件，存在的话，加后缀
		if (ossUtil.doesObjectExist("yf-hr-efile-source", key,CommonConstants.ZERO_INT)) {
			// 文件存在，添加后缀
			int lastDotIndex = fileName.lastIndexOf('.');
			String nameWithoutExt;
			String extension;

			if (lastDotIndex > 0) {
				nameWithoutExt = fileName.substring(0, lastDotIndex);
				extension = fileName.substring(lastDotIndex);
			} else {
				nameWithoutExt = fileName;
				extension = "";
			}
			key = filePath + "/" + nameWithoutExt + "_" + System.currentTimeMillis() + extension;
			fileName = nameWithoutExt + "_" + System.currentTimeMillis() + extension;
		}

		boolean flag = ossUtil.uploadFileByStream(file.getInputStream(), key, "yf-hr-efile-source");
		TAttaInfo attaInfo;
		URL url;
		if (flag) {
			attaInfo = initUnitAttaForInsert(fileName, key, file.getSize());
			attaInfo.setRelationType(type);
			try {
				attaInfo.setDomainId(domainId);
				attaInfo.setTaskId(taskId);

			// 优先使用传入的用户信息（支持异步场景）
			if (Common.isNotNull(userId) && StrUtil.isNotBlank(userId)) {
				attaInfo.setCreateBy(userId);
				attaInfo.setCreateName(userName);
			} else {
				// 从上下文获取（同步场景）
				try {
					YifuUser user = SecurityUtils.getUser();
					if (user != null) {
						attaInfo.setCreateBy(user.getId());
						attaInfo.setCreateName(user.getNickname());
					}
				} catch (Exception e) {
					log.warn("获取用户上下文失败，附件创建人将为空", e);
				}
			}
				
				attaInfo = tAttaInfoService.add(attaInfo);
			} catch (Exception e) {
				log.error("OSS文件上传异常：" + e.getMessage());
				ossUtil.deleteObject("yf-hr-efile-source", key);
				return R.failed("上传异常:" + e.getMessage());
			}
			url = ossUtil.getObjectUrl("yf-hr-efile-source", attaInfo.getAttaSrc());
			attaInfo.setAttaUrl(String.valueOf(url));
			return R.ok(attaInfo);
		} else {
			return R.failed("fail:上传异常");
		}
	}

	@Override
	public R<FileVo> uploadImg(MultipartFile file, String filePath, String type, String domain) throws IOException {
		if (null == file) {
			return R.failed("文件删除异常，请重新上传！");
		}
		String fileName = file.getOriginalFilename();
		if (Common.isEmpty(fileName)) {
			return R.failed("文件名不能为空！");
		}
		if (fileName.length() > 100) {
			return R.failed("文件名不能超过100个字符！");
		}
		//filePath不传默认存储空间的根目录
		//jpg,jpeg,png,bmp
		String key = "";
		if (Common.isNotNull(filePath)) {
			key = filePath + "/" + System.currentTimeMillis() + fileName;
		} else {
			key = System.currentTimeMillis() + fileName;
		}
		if (!Common.checkFile(key)) {
			return R.failed("非法上传类型！");
		}
		boolean flag = ossUtil.uploadFileByStream(file.getInputStream(), key, "yf-hr-efile-source");
		FileVo fileVo;
		TAttaInfo attaInfo;
		URL url;
		if (flag) {
			attaInfo = initUnitAttaForInsert(fileName, key, file.getSize());
			attaInfo.setRelationType(type);
			try {
				attaInfo.setDomainId(domain);
				attaInfo = tAttaInfoService.add(attaInfo);
			} catch (Exception e) {
				log.error("OSS文件上传接口异常：" + e.getMessage());
				ossUtil.deleteObject("yf-hr-efile-source", key);
				return R.failed("fail:" + e.getMessage());
			}
			//有实体id则插入关系，用于编辑
			if (Common.isNotNull(domain)) {
				url = ossUtil.getObjectUrl("yf-hr-efile-source", attaInfo.getAttaSrc());
				fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
				return R.ok(fileVo, "success");
			}
			url = ossUtil.getObjectUrl("yf-hr-efile-source", attaInfo.getAttaSrc());
			fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
			return R.ok(fileVo, "success");
		} else {
			return R.failed("fail:上传失败");
		}
	}

	/**
	 * 对象初始化
	 * @param fileName
	 * @param key
	 * @param fileSize
	 * @return
	 */
	private TAttaInfo initUnitAttaForInsert(String fileName, String key, long fileSize) {
		TAttaInfo unitAtta = new TAttaInfo();
		char slash = '/';
		char point = '.';
		if (fileName.lastIndexOf(slash) >= 0) {
			unitAtta.setAttaName(fileName.substring(fileName.lastIndexOf(slash)));
		} else {
			unitAtta.setAttaName(fileName);
		}
		unitAtta.setAttaSize(fileSize);
		unitAtta.setAttaSrc(key);
		if (key.lastIndexOf(point) >= 0) {
			unitAtta.setAttaType(key.substring(key.lastIndexOf(point)));
		}
		unitAtta.setCreateTime(LocalDateTime.now());
		return unitAtta;
	}
	/**
	 * @Author fxj
	 * @Description 整合接口
	 * @Date 15:24 2024/9/24
	 * @Param
	 * @return
	**/
	@Override
	public R uploadAsso(MultipartFile file, String filePath, String type, String domain, String uploadType){
		return uploadAsso(file, filePath, type, domain, uploadType, null);
	}

	@Override
	public R uploadAsso(MultipartFile file, String filePath, String type, String domain, String uploadType, String taskId){
		return getR(file, filePath, type, domain, uploadType, taskId);
	}

	public R getR(MultipartFile file, String filePath, String type, String domain, String uploadType) {
		return getR(file, filePath, type, domain, uploadType, null);
	}

	public R getR(MultipartFile file, String filePath, String type, String domain, String uploadType, String taskId) {
		maxLimit = configLimitMapper.getSysConfigLimitByKey("UPLOAD_MAX_LIMIT");
		if (atomicInteger.incrementAndGet() <= maxLimit){
			try {
				if (CommonConstants.ZERO_STRING.equals(uploadType)){
					return uploadImg(file, filePath, type, domain);
				}else if (CommonConstants.ONE_STRING.equals(uploadType)){
					return uploadFileReturnAtta(file, filePath, type, domain, taskId);
				}
			}catch (Exception e){
				log.error("附件上传异常：",e);
			}finally {
				atomicInteger.decrementAndGet();
			}
		}else {
			atomicInteger.decrementAndGet();
			log.error("超出阈值："+ResultConstants.FILE_UPLOADING_DATA);
			return  R.failed(ResultConstants.FILE_UPLOADING_DATA);
		}

		return null;
	}

	@Override
	public boolean checkFileExists(String filePath) {
		try {
			return ossUtil.doesObjectExist("yf-hr-efile-source", filePath,CommonConstants.ZERO_INT);
		} catch (Exception e) {
			log.error("检查文件是否存在失败：{}", filePath, e);
			return false;
		}
	}

}