package com.yushu.system.service.impl;

import java.io.File;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.yushu.common.config.FileStorageConfig;
import com.yushu.common.utils.DateUtils;
import com.yushu.common.utils.SecurityUtils;
import com.yushu.common.utils.StringUtils;
import com.yushu.common.utils.file.FileUploadUtils;
import com.yushu.common.utils.file.MimeTypeUtils;
import com.yushu.common.exception.ServiceException;
import com.yushu.system.mapper.SysFileMapper;
import com.yushu.system.domain.SysFileInfo;
import com.yushu.system.service.ISysFileService;

/**
 * 文件Service业务层处理
 * 
 * @author yushu
 * @date 2024-11-15
 */
@Service
public class SysFileServiceImpl implements ISysFileService 
{
    @Autowired
    private SysFileMapper sysFileMapper;
    
    @Autowired
    private FileStorageConfig fileStorageConfig;

    /**
     * 查询文件
     * 
     * @param fileId 文件主键
     * @return 文件
     */
    @Override
    public SysFileInfo selectSysFileByFileId(Long fileId)
    {
        return sysFileMapper.selectSysFileByFileId(fileId);
    }

    /**
     * 查询文件列表
     * 
     * @param sysFile 文件
     * @return 文件
     */
    @Override
    public List<SysFileInfo> selectSysFileList(SysFileInfo sysFile)
    {
        return sysFileMapper.selectSysFileList(sysFile);
    }

    /**
     * 上传文件
     * 
     * @param file 文件
     * @param folderId 文件夹ID
     * @param fileName 自定义文件名
     * @return 结果
     */
    @Override
    public SysFileInfo uploadFile(MultipartFile file, Long folderId, String fileName) throws Exception
    {
        if (file.isEmpty())
        {
            throw new ServiceException("上传文件不能为空");
        }
        
        // 获取文件原始名称
        String originalFilename = file.getOriginalFilename();
        
        // 获取文件扩展名
        String extension = "";
        if (originalFilename != null && originalFilename.contains("."))
        {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        // 使用自定义文件名或原始文件名
        String displayName = StringUtils.isNotEmpty(fileName) ? fileName : originalFilename;
        
        // 生成存储文件名（带时间戳，避免重复）
        String storageFileName = DateUtils.dateTimeNow() + "_" + System.nanoTime() + extension;
        
        // 获取存储路径
        String basePath = fileStorageConfig.getLocal().getNormalizedBasePath();
        String datePath = DateUtils.datePath();  // 按日期分目录
        String fullPath = basePath + File.separator + datePath;
        
        // 确保目录存在
        File dir = new File(fullPath);
        if (!dir.exists())
        {
            dir.mkdirs();
        }
        
        // 保存文件
        String filePath = fullPath + File.separator + storageFileName;
        file.transferTo(new File(filePath));
        
        // 构建相对路径（用于数据库存储和URL访问，统一使用正斜杠）
        String relativePath = datePath + "/" + storageFileName;
        
        // 创建文件记录
        SysFileInfo sysFile = new SysFileInfo();
        sysFile.setFolderId(folderId != null ? folderId : 0L);
        sysFile.setFileName(displayName);
        sysFile.setOriginalName(originalFilename);
        sysFile.setFilePath(relativePath);
        sysFile.setFileSize(file.getSize());
        sysFile.setFileType(extension.replace(".", ""));
        sysFile.setMimeType(file.getContentType());
        sysFile.setUserId(SecurityUtils.getUserId());
        sysFile.setUserName(SecurityUtils.getUsername());
        sysFile.setDownloadCount(0);
        sysFile.setCreateTime(DateUtils.getNowDate());
        sysFile.setCreateBy(SecurityUtils.getUsername());
        
        sysFileMapper.insertSysFile(sysFile);
        
        return sysFile;
    }

    /**
     * 修改文件
     * 
     * @param sysFile 文件
     * @return 结果
     */
    @Override
    public int updateSysFile(SysFileInfo sysFile)
    {
        sysFile.setUpdateTime(DateUtils.getNowDate());
        return sysFileMapper.updateSysFile(sysFile);
    }

    /**
     * 批量删除文件
     * 
     * @param fileIds 需要删除的文件主键
     * @return 结果
     */
    @Override
    public int deleteSysFileByFileIds(Long[] fileIds)
    {
        // 删除物理文件
        String basePath = fileStorageConfig.getLocal().getNormalizedBasePath();
        for (Long fileId : fileIds)
        {
            SysFileInfo sysFile = sysFileMapper.selectSysFileByFileId(fileId);
            if (sysFile != null)
            {
                String fullPath = basePath + File.separator + sysFile.getFilePath();
                File file = new File(fullPath);
                if (file.exists())
                {
                    file.delete();
                }
            }
        }
        
        return sysFileMapper.deleteSysFileByFileIds(fileIds);
    }

    /**
     * 删除文件信息
     * 
     * @param fileId 文件主键
     * @return 结果
     */
    @Override
    public int deleteSysFileByFileId(Long fileId)
    {
        // 删除物理文件
        SysFileInfo sysFile = sysFileMapper.selectSysFileByFileId(fileId);
        if (sysFile != null)
        {
            String basePath = fileStorageConfig.getLocal().getNormalizedBasePath();
            String fullPath = basePath + File.separator + sysFile.getFilePath();
            File file = new File(fullPath);
            if (file.exists())
            {
                file.delete();
            }
        }
        
        return sysFileMapper.deleteSysFileByFileId(fileId);
    }
    
    /**
     * 下载文件
     * 
     * @param fileId 文件ID
     * @return 文件对象
     */
    @Override
    public SysFileInfo downloadFile(Long fileId)
    {
        SysFileInfo sysFile = sysFileMapper.selectSysFileByFileId(fileId);
        if (sysFile == null)
        {
            throw new ServiceException("文件不存在");
        }
        
        // 增加下载次数
        sysFileMapper.increaseDownloadCount(fileId);
        
        return sysFile;
    }
    
    /**
     * 移动文件
     * 
     * @param fileId 文件ID
     * @param targetFolderId 目标文件夹ID
     * @return 结果
     */
    @Override
    public int moveFile(Long fileId, Long targetFolderId)
    {
        SysFileInfo sysFile = new SysFileInfo();
        sysFile.setFileId(fileId);
        sysFile.setFolderId(targetFolderId);
        sysFile.setUpdateTime(DateUtils.getNowDate());
        return sysFileMapper.updateSysFile(sysFile);
    }
    
    /**
     * 复制文件
     * 
     * @param fileId 文件ID
     * @param targetFolderId 目标文件夹ID
     * @return 结果
     */
    @Override
    public int copyFile(Long fileId, Long targetFolderId)
    {
        // 查询原文件
        SysFileInfo originalFile = sysFileMapper.selectSysFileByFileId(fileId);
        if (originalFile == null)
        {
            throw new ServiceException("文件不存在");
        }
        
        // 创建新文件记录
        SysFileInfo newFile = new SysFileInfo();
        newFile.setFolderId(targetFolderId);
        newFile.setFileName(generateCopyFileName(originalFile.getFileName(), targetFolderId));
        newFile.setOriginalName(originalFile.getOriginalName());
        newFile.setFilePath(originalFile.getFilePath()); // 共享同一个物理文件
        newFile.setFileSize(originalFile.getFileSize());
        newFile.setFileType(originalFile.getFileType());
        newFile.setMimeType(originalFile.getMimeType());
        newFile.setUserId(SecurityUtils.getUserId());
        newFile.setUserName(SecurityUtils.getUsername());
        newFile.setDownloadCount(0);
        newFile.setCreateTime(DateUtils.getNowDate());
        
        return sysFileMapper.insertSysFile(newFile);
    }
    
    /**
     * 生成复制文件名
     */
    private String generateCopyFileName(String originalName, Long targetFolderId)
    {
        // 分离文件名和扩展名
        String nameWithoutExt = originalName;
        String ext = "";
        int lastDot = originalName.lastIndexOf('.');
        if (lastDot > 0)
        {
            nameWithoutExt = originalName.substring(0, lastDot);
            ext = originalName.substring(lastDot);
        }
        
        // 检查目标文件夹中是否存在同名文件
        String newName = originalName;
        int copyNum = 1;
        while (fileNameExists(newName, targetFolderId))
        {
            newName = nameWithoutExt + " (" + copyNum + ")" + ext;
            copyNum++;
        }
        
        return newName;
    }
    
    /**
     * 检查文件名是否存在
     */
    private boolean fileNameExists(String fileName, Long folderId)
    {
        SysFileInfo query = new SysFileInfo();
        query.setFileName(fileName);
        query.setFolderId(folderId);
        List<SysFileInfo> files = sysFileMapper.selectSysFileList(query);
        return files != null && !files.isEmpty();
    }
}
