/*
 *      Copyright (c) 2018-2028, Chill Zhuang 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 dreamlu.net 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: Chill 庄骞 (smallchill@163.com)
 */
package org.security.trans.common.service.impl;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.security.common.config.CommonProperties;
import org.security.desk.feign.IImagesClient;
import org.security.ht.entity.common.File;
import org.security.trans.common.mapper.FileMapper;
import org.security.trans.common.service.IFileService;
import org.security.trans.common.service.UploadService;
import org.security.ht.vo.common.FileVO;
import org.security.ht.vo.common.UploadVO;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 公共-附件表 服务实现类
 *
 * @author BladeX
 * @since 2022-07-04
 */
@AllArgsConstructor
@Service
@Slf4j
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements IFileService {

	private final UploadService uploadService;
	private final IImagesClient iImagesClient;
	private final CommonProperties commonProperties;

	@Override
	public IPage<FileVO> selectFilePage(IPage<FileVO> page, FileVO file) {
		return page.setRecords(baseMapper.selectFilePage(page, file));
	}

	@Override
	public void saveAttachments(List<UploadVO> relevantAttachments, String aimId) {
		List<File> list = new ArrayList<>();
		if (Func.isNotEmpty(relevantAttachments)) {
			relevantAttachments.forEach(item -> {
				if (Func.isEmpty(item.getId())) {
					File file = new File();
					file.setId(item.getId());
					file.setFileName(item.getName());
					file.setLocalUrl(item.getUrl());
					file.setLinkId(String.valueOf(aimId));
					file.setContentId(item.getContentId());
					file.setDeptId(AuthUtil.getDeptId());
					file.setFormat(FileUtil.getSuffix(item.getName()));
					file.setBusiBeginDate(item.getBusiBeginDate());
					file.setGroupName(item.getGroupName());
					file.setEncrypt(item.getEncrypt());
					list.add(file);
				}
			});
			this.saveBatch(list);
		}
	}

	@Override
	public List<UploadVO> getAttachments(String id, String groupName) {
		List<UploadVO> uploadVOList = new ArrayList<>();
		if (Func.isNotEmpty(id) && Func.isNotEmpty(groupName)) {
			LambdaQueryWrapper<File> queryWrapper = new QueryWrapper<File>().lambda()
				.eq(File::getLinkId, String.valueOf(id)).eq(File::getGroupName, groupName)
				.orderByDesc(File::getCreatedTime);
			List<File> list = this.list(queryWrapper);
			if (Func.isNotEmpty(list)) {
				list.forEach(item -> {
					UploadVO uploadVO = Func.copy(item, UploadVO.class);
					uploadVO.setFileType(item.getFormat());
					uploadVO.setName(item.getFileName().substring(item.getFileName().indexOf('-') + 1));
					uploadVO.setId(item.getId());
					uploadVO.setEncrypt(item.getEncrypt());
					if (Func.isNotEmpty(item.getLocalUrl())) {
						//判断该文件是否存在于本地文件夹内
						java.io.File localFile = new java.io.File(item.getLocalUrl());
						//本地文件不存在
						if (!localFile.exists()) {
							//调用影像平台
							R<String> fileUrl = iImagesClient.getFileData(item.getBusiBeginDate(), item.getContentId(), item.getFileName());
							uploadVO.setUrl(fileUrl.getData());
						}//本地文件已经存在
						else {
							R<String> fileSavePath = iImagesClient.getFileSavePath();
							String url;
							if (fileSavePath.isSuccess() && null != fileSavePath.getData() && fileSavePath.getData().length() >= 6) {
								url = item.getLocalUrl().substring(fileSavePath.getData().length() - 6);
							} else {
								url = item.getLocalUrl();
							}
							uploadVO.setUrl(url);
						}
					}
					uploadVOList.add(uploadVO);
				});
			}
			return uploadVOList;
		}
		return uploadVOList;
	}

	@Override
	public boolean removeFileData(List<String> detailIdList) {
		ArrayList<String> fileIdList = new ArrayList<>();
		detailIdList.forEach(item -> {
			List<File> list = this.list(new QueryWrapper<File>().lambda().eq(Func.isNotBlank(item), File::getLinkId, item));
			if (Func.isNotEmpty(list)) {
				list.forEach(f -> {
					//删除本地服务器和影像平台相关附件
					removeServerFile(f);
					//删除本地库数据记录
					fileIdList.add(f.getId());
				});
			}
		});
		if (Func.isNotEmpty(fileIdList)) {
			return this.removeByIds(fileIdList);
		}
		return true;
	}

	/**
	 *删除本地服务器和影像平台相关附件
	 */
	private boolean removeServerFile(File f) {
		//移除本地服务器文件资源
		java.io.File file = new java.io.File(f.getLocalUrl());
		boolean b = file.delete();
		//本地服务器文件删除成功
		if (b){
			//移除影像平台附件资源
			R r = iImagesClient.removeFileData(f.getBusiBeginDate(), f.getContentId());
			if (!r.isSuccess()) {
				return false;
			}
		}
		return true;
	}


	@Override
	public boolean removeFileData2(List<String> detailIdList) {
		List<File> list = this.list(new QueryWrapper<File>().lambda().in(Func.isNotEmpty(detailIdList), File::getId, detailIdList));
		if (Func.isNotEmpty(list)) {
			list.forEach(file -> {
				boolean b = removeServerFile(file);
				if (b){
					this.removeByIds(detailIdList);
					log.info("附件删除成功");
				}else {
					log.error("本地服务器或影像平台删除附件失败");
				}
			});
			return true;
		}else {
			return false;
		}
	}


	@Override
	public boolean update(MultipartFile file, String id) throws IOException {
		UploadVO uploadVO = uploadService.uploadSingleFile(file, null, null);
		uploadVO.setId(id);
		File fileEntity = new File();
		fileEntity.setId(id);
		fileEntity.setFormat(FileUtil.getSuffix(uploadVO.getName()));
		fileEntity.setFileName(uploadVO.getName());
//		fileEntity.setUrl(uploadVO.getUrl());
		return this.updateById(fileEntity);
	}
}
