package org.dromara.system.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysOss;
import org.dromara.system.domain.bo.SysOssBo;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.mapper.SysOssMapper;
import org.dromara.system.service.ISysFileUploadService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 文件上传 服务层实现
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
public class SysFileUploadServiceImpl implements ISysFileUploadService {


    @Value("${ruoyi.profile}")
    private String profile;

    @Value("${ruoyi.host}")
    private String host;

    private final SysOssMapper baseMapper;

    @Override
    public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
        Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public List<SysOssVo> listByIds(Collection<Long> ossIds) {
        List<SysOssVo> sysOssVos = baseMapper.selectVoBatchIds(ossIds);
        return sysOssVos;
    }

    @Override
    public String selectUrlByIds(String ossIds) {
        List<String> list = new ArrayList<>();
        for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) {
            SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
            if (ObjectUtil.isNotNull(vo)) {
                list.add(vo.getUrl());
            }
        }
        return String.join(StringUtils.SEPARATOR, list);
    }

    private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName());
        lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName());
        lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix());
        lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl());
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
            SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
        lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy());
        lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService());
        lqw.orderByAsc(SysOss::getOssId);
        return lqw;
    }

    @Override
    public SysOssVo getById(Long ossId) {
        return baseMapper.selectVoById(ossId);
    }


    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 做一些业务上的校验,判断是否需要校验
        }
        System.out.println(ids);
        List<SysOss> list = baseMapper.selectBatchIds(ids);
        for (SysOss sysOss:list) {
            this.delFile(sysOss.getFileName());
        }

        return baseMapper.deleteBatchIds(ids) > 0;
    }


    public SysOssVo saveResult(String originalfileName,String url,String fileName) {
        SysOss oss = new SysOss();
        String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
        oss.setUrl(host+"/system/file/download/"+url);
        oss.setFileSuffix(suffix);
        oss.setFileName(fileName);
        oss.setOriginalName(originalfileName);

        boolean flag = baseMapper.insert(oss) > 0;
        if (!flag) {
            throw new ServiceException("文件信息保存出错");
        }
        SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);
        return sysOssVo;
    }
    public  boolean delFile(String fileName){
        String parentPath = profile;
        File dest = new File(parentPath, fileName);
        if (dest.exists()) {
            Boolean isDelete = FileSystemUtils.deleteRecursively(dest);
            if (!isDelete) {
                throw new ServiceException("删除文件失败!");
            }
        }
        return true;
    }

    @Override
    public Boolean deleteOssById(Long id) {
        SysOss sysOss = baseMapper.selectById(id);

        String deletePath = profile + "/" +sysOss.getFileName();

        if (deleteFileRecursive(deletePath)) {
            // 执行特定文件夹删除操作
            String fileExtension = getFileExtensionFromPath(deletePath);
            if (fileExtension.equalsIgnoreCase("pdf")) {
                String subFolderPath = getSubFolderPath(deletePath, "pdf");
                System.out.println("8." + subFolderPath);
                deleteFolder(subFolderPath); // 修改这一行
            } else if (fileExtension.equalsIgnoreCase("doc") || fileExtension.equalsIgnoreCase("docx")) {
                String subFolderPath = getSubFolderPath(deletePath, "word");
                System.out.println("9." + subFolderPath);
                deleteFolder(subFolderPath); // 修改这一行
            }

            // 删除数据库中的文件记录
            int deleteCount = baseMapper.deleteById(sysOss);
            System.out.println("文件删除成功");
            return true; // 文件删除成功
        } else {
            System.out.println("文件删除失败");
            return false; // 文件删除失败
        }
    }

    // 从文件路径中获取文件扩展名
    private String getFileExtensionFromPath(String filePath) {
        int dotIndex = filePath.lastIndexOf(".");
        if (dotIndex >= 0 && dotIndex < filePath.length() - 1) {
            return filePath.substring(dotIndex + 1).toLowerCase();
        }
        System.out.println("10." + dotIndex);
        return "";
    }

    // 根据文件路径和指定的文件夹名称获取子文件夹路径
    private String getSubFolderPath(String filePath, String folderName) {
        int index = filePath.lastIndexOf(File.separator + folderName + File.separator);
        if (index != -1) {
            return filePath.substring(0, index);
        }
        return filePath;
    }

    /**
     * 删除文件
     *
     * @param ids 文件
     * @return
     */
    public static boolean deleteFileRecursive(String ids) {
        File file = new File(ids);
        System.out.println("11." + file.getPath());
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        System.out.println(false);
        return false;
    }

    // 递归删除文件夹及其内容
    private void deleteFolder(String filePath) {
        File folder = new File(filePath);
        System.out.println("12." + folder);
        if (folder.exists()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteFolder(file.getPath()); // 使用完整的文件夹路径
                    } else {
                        file.delete();
                    }
                }
                folder.delete();
            }
        }
    }
}
