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

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 com.yifu.cloud.plus.v1.yifu.social.entity.SysHouseHoldInfo;
import com.yifu.cloud.plus.v1.yifu.social.entity.TAttaInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.SysConfigLimitMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.FileUploadService;
import com.yifu.cloud.plus.v1.yifu.social.service.SysHouseHoldInfoService;
import com.yifu.cloud.plus.v1.yifu.social.service.TAttaInfoService;
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 SysHouseHoldInfoService sysHouseHoldInfoService;

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

	private final SysConfigLimitMapper configLimitMapper;

	@Override
	public R<TAttaInfo> uploadFileReturnAtta(MultipartFile file, String filePath, Integer 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(String.valueOf(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, Integer 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(String.valueOf(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)) {
				if (type == 1) {
					// 户配置上传公章，将户配置变为 有章
					this.updateSysHouseHoldInfoIsSign(domain, CommonConstants.ZERO_STRING);
				}
				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 domainId 主键
	 * @param isSign 0是1否
	 * @Description: 更新户的章是否有
	 * @Author: hgw
	 * @Date: 2025/5/19 10:59
	 * @return: void
	 **/
	public void updateSysHouseHoldInfoIsSign(String domainId, String isSign) {
		// 户配置上传公章，将户配置变为 有章
		SysHouseHoldInfo sysHouseHoldInfo = sysHouseHoldInfoService.getById(domainId);
		if (sysHouseHoldInfo != null) {
			sysHouseHoldInfo.setIsSign(isSign);
			sysHouseHoldInfoService.updateById(sysHouseHoldInfo);
		}
	}

	private R<FileVo> uploadImg2(InputStream fileIn, String filePath, Integer 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) {
			log.info("文件：" + fileName + "上传至存储空间" + ossUtil.getBucketName() + "成功！");
			attaInfo = initUnitAttaForInsert(fileName, key, 0);
			attaInfo.setRelationType(String.valueOf(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;
	}

	/**
	 * @return
	 * @Author fxj
	 * @Description 整合接口
	 * @Date 15:24 2024/9/24
	 * @Param
	 **/
	@Override
	public R uploadAsso(MultipartFile file, String filePath, Integer type, String domain, String uploadType) {
		return getR(file, filePath, type, domain, uploadType);
	}

	public R getR(MultipartFile file, String filePath, Integer 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;
	}

}