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

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.SysConfigLimitMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.FileUploadService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TAttaInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.utils.QrCodeUtil;
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.constant.SecurityConstants;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

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

	private final OSSUtil ossUtil;

	private final TAttaInfoService tAttaInfoService;

	private final QrCodeUtil codeUtil;

	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 {
		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 + "/" + System.currentTimeMillis() + fileName;
		} else {
			key = System.currentTimeMillis() + fileName;
		}
		if (!Common.checkFile(key)) {
			return R.failed("非法上传类型："+fileName);
		}
		boolean flag = ossUtil.uploadFileByStream(file.getInputStream(), key, null);
		TAttaInfo attaInfo;
		URL url;
		if (flag) {
			log.info("文件：" + fileName + "上传到存储空间" + ossUtil.getBucketName() + "成功！");
			attaInfo = initUnitAttaForInsert(fileName, key, file.getSize());
			attaInfo.setRelationType(type);
			try {
				attaInfo.setDomainId(domainId);

				Set<String> dbAuthsSet = new HashSet<>();
				Collection<? extends GrantedAuthority> authorities = AuthorityUtils
						.createAuthorityList(dbAuthsSet.toArray(new String[0]));
				YifuUser user = new YifuUser("2", 1L, "", "预入职扫码",
						"预入职扫码", "0", SecurityConstants.BCRYPT + "123456",
						"12345678911", true, true, true,
						true,
						"1", authorities, "1",
						null, null,
						null,null);
				attaInfo.setCreateBy(user.getId());
				attaInfo.setCreateName(user.getNickname());
				attaInfo = tAttaInfoService.add(attaInfo);
			} catch (Exception e) {
				log.error("OSS文件上传异常：" + e.getMessage());
				ossUtil.deleteObject(null, key);
				return R.failed("上传异常:" + e.getMessage());
			}
			url = ossUtil.getObjectUrl(null, 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, null);
		FileVo fileVo;
		TAttaInfo attaInfo;
		URL url;
		if (flag) {
			log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
			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(null, key);
				return R.failed("fail:" + e.getMessage());
			}
			//有实体id则插入关系，用于编辑
			if (Common.isNotNull(domain)) {
				url = ossUtil.getObjectUrl(null, attaInfo.getAttaSrc());
				fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
				return R.ok(fileVo, "success");
			}
			url = ossUtil.getObjectUrl(null, attaInfo.getAttaSrc());
			fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
			return R.ok(fileVo, "success");
		} else {
			return R.failed("fail:上传失败");
		}
	}

	private R<FileVo> uploadImg2(InputStream fileIn, String filePath, String type, String domain,String fileName) throws IOException {
		if (null == fileIn) {
			return R.failed("文件上传异常，请重新上传！");
		}
		if (Common.isEmpty(fileName)) {
			return R.failed("文件名不能为空！");
		}
		//filePath不传默认存储空间的根目录
		//jpg,jpeg,png,bmp
		String key = System.currentTimeMillis() + fileName;
		boolean flag = ossUtil.uploadFileByStream(fileIn, key, null);
		FileVo fileVo;
		TAttaInfo attaInfo;
		URL url;
		if (flag) {
			attaInfo = initUnitAttaForInsert(fileName, key, 0);
			attaInfo.setRelationType(type);
			try {
				attaInfo.setDomainId(domain);
				attaInfo = tAttaInfoService.add(attaInfo);
			} catch (Exception e) {
				log.error("OSS文件上传接口异常：" + e.getMessage());
				ossUtil.deleteObject(null, key);
				return R.failed("fail:" + e.getMessage());
			}
			//有实体id则插入关系，用于编辑
			if (Common.isNotNull(domain)) {
				url = ossUtil.getObjectUrl(null, attaInfo.getAttaSrc());
				fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
				return R.ok(fileVo, "success");
			}
			url = ossUtil.getObjectUrl(null, 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;
	}

	@Override
	public R<FileVo> createQrCode(String domainId, String url, String name) {
		TAttaInfo attaInfo = tAttaInfoService.getOne(Wrappers.<TAttaInfo>query().lambda().eq(TAttaInfo::getAttaSrc,domainId).last(CommonConstants.LAST_ONE_SQL));
		FileVo fileVo;
		if (Common.isNotNull(attaInfo)){
			fileVo = new FileVo(attaInfo.getId(), attaInfo.getAttaName(), url.toString());
			return R.ok(fileVo);
		}
		InputStream in  = codeUtil.createPng(url);
		try {
			return this.uploadImg2(in,"mvp_qr",CommonConstants.EIGHT_STRING,domainId,"output_qrcode.png");
		} catch (IOException e) {
			log.error("获取二维码失败",e);
			return R.failed(CommonConstants.RESULT_DATA_FAIL);
		}finally{
			if (Common.isNotNull(in)){
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/**
	 * @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 getR(file, filePath, type, domain, uploadType);
	}

	public R getR(MultipartFile file, String filePath, String type, String domain, String uploadType) {
		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);
				}
			}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;
	}

}