package org.springblade.file.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.file.convert.BusinessAttachmentConvert;
import org.springblade.file.mapper.BusinessAttachmentMapper;
import org.springblade.file.pojo.dto.BusinessAttachmentAddDTO;
import org.springblade.file.pojo.dto.BusinessAttachmentBatchAddDTO;
import org.springblade.file.pojo.dto.BusinessAttachmentDeleteDTO;
import org.springblade.file.pojo.dto.BusinessAttachmentQueryDTO;
import org.springblade.file.pojo.entity.BusinessAttachment;
import org.springblade.file.pojo.vo.BusinessAttachmentVO;
import org.springblade.file.service.IBusinessAttachmentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务附件信息表 服务实现类
 *
 * @author BladeX
 * @since 2024-09-04
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class BusinessAttachmentServiceImpl extends ServiceImpl<BusinessAttachmentMapper, BusinessAttachment> implements IBusinessAttachmentService {

	private final BusinessAttachmentConvert convert;

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean saveAndRemove(BusinessAttachmentBatchAddDTO param) {
		if (param == null) {
			log.warn("批量保存业务附件，参数为空");
			return false;
		}
		if (param.isRemove() && param.getBizId() != null) {
			// 先删除
			this.removeByBizIds(List.of(param.getBizId()));
		}
		List<BusinessAttachment> addList = convert.dto2entities(param);
		if (CollectionUtil.isNotEmpty(addList)) {
			return this.saveBatch(addList);
		}
		return true;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean saveAndRemove(List<BusinessAttachmentAddDTO> params, BusinessAttachmentDeleteDTO deleteParam) {
		boolean hasBizIds = deleteParam != null && deleteParam.isDelete() && CollectionUtil.isNotEmpty(deleteParam.getBizIds());
		if (hasBizIds) {
			// bizIds不为空，先删除
			this.removeByBizIdsAndCodes(deleteParam.getBizIds(), deleteParam.getBizCodes());
		}
		if (CollectionUtil.isEmpty(params)) {
			log.warn("保存业务附件，参数为空");
			return true;
		}
		if (!hasBizIds && (deleteParam == null || deleteParam.isDelete())) {
			// bizIds为空，从参数提取bizIds，再删除
			// 删除参数为空，默认删除，删除参数中delete为true默认删除，false不删除
			List<Long> bizIds = params.stream()
					.map(BusinessAttachmentAddDTO::getBizId)
					.distinct()
					.toList();
			this.removeByBizIds(bizIds);
		}

		List<BusinessAttachment> businessAttachments = convert.dtos2entities(params);

		// 按照业务id分组排序
		Map<Long, List<BusinessAttachment>> bizIdAttachmentsMap = businessAttachments.stream()
				.collect(Collectors.groupingBy(BusinessAttachment::getBizId));
		String tenantId = AuthUtil.getTenantId();
		for (Map.Entry<Long, List<BusinessAttachment>> entry : bizIdAttachmentsMap.entrySet()) {
			int i = 1;
			for (BusinessAttachment businessAttachment : entry.getValue()) {
				businessAttachment.setId(IdWorker.getId());
				// 处理排序
				businessAttachment.setSort(i++);
				if (StringUtil.isBlank(tenantId)) {
					businessAttachment.setTenantId(BladeConstant.ADMIN_TENANT_ID);
				}
			}
		}
		return this.saveBatch(businessAttachments);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean removeByBizIds(List<Long> bizIds) {
		return this.removeByBizIdsAndCodes(bizIds, null);
	}

	@Override
	public List<BusinessAttachmentVO> queryList(BusinessAttachmentQueryDTO param) {
		return baseMapper.queryList(param);
	}

	/**
	 *  批量删除
	 * @param bizIds 业务id列表，为空，不删除
	 * @param bizCodes 业务编码列表，为空，删除所有
	 * @return
	 */
	private boolean removeByBizIdsAndCodes(List<Long> bizIds, List<String> bizCodes) {
		if (CollectionUtil.isEmpty(bizIds)) {
			log.warn("删除附件，参数为空");
			return false;
		}
		List<Long> ids = this.list(Wrappers.<BusinessAttachment>lambdaQuery()
						.in(BusinessAttachment::getBizId, bizIds)
						// 业务编码列表不为空，添加业务编码查询条件
						.in(CollectionUtil.isNotEmpty(bizCodes), BusinessAttachment::getBizCode, bizCodes)
				).stream()
				.map(BusinessAttachment::getId)
				.toList();
		if (CollectionUtil.isNotEmpty(ids)) {
			return this.removeBatchByIds(ids);
		}
		return true;
	}
}
