package com.ruoyi.file.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.file.mapper.FilesMapper;
import com.ruoyi.file.service.FileUploadResponse;
import com.ruoyi.file.service.FilesService;
import com.ruoyi.file.domain.FilesUpload;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class FilesServiceImpl extends ServiceImpl<FilesMapper, FilesUpload> implements FilesService {
    @Value("${file.path}")
    private String filesUploadPath;//获取文件路径

    @Value("${file.domain}")
    private String filesUploadDomain;//文件域名

    @Value("${file.prefix}")
    private String filesPrefix;//文件前缀



    @Override
    public FileUploadResponse upload(MultipartFile file, Long userid, String userName, String refererPath) {

        // 获取当前登录用户昵称（如果可用）
//        String userName = SecurityUtils.getUsername();

        // 文件夹路径名称
        String originalFilename = file.getOriginalFilename();

        //文件大小
        double size = file.getSize() / (1024.0);

        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
//        String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

        //文件类型
        String type = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();

        // 按照年月创建文件夹
        String yearMonth = now.format(DateTimeFormatter.ofPattern("yyyyMM"));
        // 获取每月递增值
        int monthIncrement = getMonthIncrement(yearMonth);
        // 新文件名格式：时间戳+每月递增值+文件类型
//        String fileUuid = timestamp + "A" + String.format("%04d", monthIncrement) + "." + type;

        // 将相对路径转化为绝对路径
        String destPath = filesUploadPath + "/" + yearMonth;

        // 新的文件地址，绝对路径+新的文件名称
//        File uploadFile = new File(destPath + "/" + fileUuid);
        File uploadFile;
        String fileUuid = originalFilename; // 初始使用原文件名
        int count = 1; // 用于生成重复文件名的序号
        while (true) {
            uploadFile = new File(destPath + "/" + fileUuid);
            if (!uploadFile.exists()) { // 如果文件不存在，直接使用该文件名
                break;
            } else { // 如果文件已存在，修改文件名
                String nameWithoutType = originalFilename.substring(0, originalFilename.lastIndexOf("."));
                fileUuid = nameWithoutType + "(" + count + ")." + type;
                count++;
            }
        }

        // 判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }

        try {
            // 存储文件到本地磁盘
            file.transferTo(uploadFile);

            // 设置文件url
            String url = filesUploadDomain + filesPrefix + "/" + yearMonth + "/" + fileUuid;

            // 将文件存储到数据库
            FilesUpload saveFile = new FilesUpload();
            saveFile.setFilesName(originalFilename);
            saveFile.setName(fileUuid);
            saveFile.setPath(destPath);
            saveFile.setType(type);
            saveFile.setSize(size); // （单位：KB）
            saveFile.setUrl(url);
            saveFile.setEnable(true);
            saveFile.setIsDelete(0);
            saveFile.setRefererPath(refererPath);
            saveFile.setCreateId(userid);
            saveFile.setCreateBy(userName);
            saveFile.setCreateTime(LocalDateTime.now());
            saveFile.setUpdateId(null);
            saveFile.setUpdateBy(null);
            saveFile.setUpdateTime(null);
            // 保存操作
            save(saveFile);

            // 返回 FileUploadResponse 对象
            return new FileUploadResponse(originalFilename, url);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取每月递增值
     * @param yearMonth 年月（格式：yyyyMM）
     * @return 递增值
     */
    private int getMonthIncrement(String yearMonth) {
        // 目标文件夹路径
        String destPath = filesUploadPath + "/" + yearMonth;
        File folder = new File(destPath);

        // 如果文件夹不存在，则递增值从1开始
        if (!folder.exists()) {
            folder.mkdirs();
            return 1;
        }

        // 获取文件夹中已有的文件数量
        File[] files = folder.listFiles();
        if (files == null || files.length == 0) {
            return 1;
        }

        // 递增值为文件夹中现有文件数量 + 1
        return files.length + 1;
    }

    @Override
    public void deleteFile(Integer id, Long userid, String userName) {
        try {
            // 根据 id 查询文件信息
            FilesUpload file = getById(id);
            if (file == null) {
                throw new RuntimeException("文件不存在，无法删除");
            }

            // 删除本地文件
            String filePath = file.getPath() + "/" + file.getName();
            File localFile = new File(filePath);
            if (localFile.exists()) {
                if (!localFile.delete()) {
                    throw new RuntimeException("文件删除失败");
                }
            }

            // 更新数据库记录
            FilesUpload updateFile = new FilesUpload();
            updateFile.setId(file.getId());
            updateFile.setFilesName(file.getFilesName());
            updateFile.setName(file.getName());
            updateFile.setPath(file.getPath());
            updateFile.setType(file.getType());
            updateFile.setSize(file.getSize());
            updateFile.setUrl(file.getUrl());
            updateFile.setEnable(false);
            updateFile.setIsDelete(1); // 设置为已删除
            updateFile.setRefererPath(file.getRefererPath());
            updateFile.setCreateId(file.getCreateId());
            updateFile.setCreateBy(file.getCreateBy());
            updateFile.setCreateTime(file.getCreateTime()); // 保留原始的 createTime
            updateFile.setUpdateId(userid);
            updateFile.setUpdateBy(userName);
            updateFile.setUpdateTime(LocalDateTime.now());

            // 提交更新到数据库
            updateById(updateFile); // 调用 updateById 方法更新数据库记录
        } catch (Exception e) {
            throw new RuntimeException("删除文件失败：" + e.getMessage());
        }
    }

    @Override
    public CommonPage<FilesUpload> queryFiles(String filesName, LocalDateTime startTime, LocalDateTime endTime, Boolean isDeleted, String fileType, String userName, int current, int size) {
        QueryWrapper<FilesUpload> queryWrapper = new QueryWrapper<>();

        // 默认查询未删除的文件
        if (isDeleted == null) {
            queryWrapper.eq("is_delete", 0);
        } else {
            queryWrapper.eq("is_delete", isDeleted ? 1 : 0);
        }

        if (filesName != null && !filesName.isEmpty()) {
            queryWrapper.like("files_name", filesName);
        }

        if (startTime != null && endTime != null) {
            queryWrapper.ge("create_time", startTime); // 大于等于起始时间
            queryWrapper.le("create_time", endTime);   // 小于等于结束时间
        } else if (startTime != null) {
            queryWrapper.ge("create_time", startTime); // 只有起始时间
        } else if (endTime != null) {
            queryWrapper.le("create_time", endTime);   // 只有结束时间
        }

        if (fileType != null && !fileType.isEmpty()) {
            queryWrapper.eq("type", fileType);
        }

        if (userName != null && !userName.isEmpty()) {
            queryWrapper.like("create_by", userName);
        }

        // 按照创建时间倒序排列
        queryWrapper.orderByDesc("create_time");

        // 创建分页请求对象
        Page<FilesUpload> page = new Page<>(current, size);

        // 执行分页查询
        IPage<FilesUpload> iPage = baseMapper.selectPage(page, queryWrapper);

        // 将 MyBatis Plus 的 IPage 转换为 CommonPage
        CommonPage<FilesUpload> commonPage = new CommonPage<>();
        commonPage.setRecords(iPage.getRecords());
        commonPage.setTotal(iPage.getTotal());
        commonPage.setSize(iPage.getSize());
        commonPage.setCurrent(iPage.getCurrent());

        return commonPage;
    }

}