package com.zjrs.zwnw.zj.util;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件工具类 - 适配 Spring Boot 3.5 & JDK 17
 */
public class FileUtil {

    /**
     * 解压 ZIP 文件
     * 适配 Zip4j 2.x 版本
     */
    public static File[] unzip(ZipFile zFile, String dest) throws ZipException {
        // 设置编码，解决中文乱码问题
        zFile.setCharset(Charset.forName("GBK"));

        if (!zFile.isValidZipFile()) {
            throw new ZipException("压缩文件不合法, 可能被损坏.");
        }

        File destDir = new File(dest);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }

        // 执行解压
        zFile.extractAll(dest);

        // 获取解压后的文件列表
        List<FileHeader> headerList = zFile.getFileHeaders();
        List<File> extractedFileList = new ArrayList<>();
        for (FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir, fileHeader.getFileName()));
            }
        }
        return extractedFileList.toArray(new File[0]);
    }

    /**
     * 递归删除文件或目录
     */
    public static boolean delFiles(File file) {
        if (file == null || !file.exists()) {
            return true;
        }
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    if (!delFiles(child)) {
                        return false;
                    }
                }
            }
        }
        return file.delete();
    }

    /**
     * 解压 Rar/7z 文件
     * 使用 Try-with-resources 确保资源在 JDK 17 下正确释放
     */
    public static List<File> unRar(File f, String filePath) throws IOException, SevenZipException {
        // 使用 try-with-resources 自动关闭资源，防止文件被锁定无法删除
        try (RandomAccessFile rdf = new RandomAccessFile(f, "r");
             RandomAccessFileInStream is = new RandomAccessFileInStream(rdf);
             IInArchive inArchive = SevenZip.openInArchive(null, is)) {

            int count = inArchive.getNumberOfItems();
            int[] indices = new int[count];
            for (int i = 0; i < count; i++) {
                indices[i] = i;
            }

            // 执行解压，这里假设 ExtractCallback 是你自定义的实现类
            inArchive.extract(indices, false, new ExtractCallback(inArchive, "366", filePath));

            return getFiles(new File(filePath));
        }
    }

    /**
     * 递归获取目录下所有文件
     */
    public static List<File> getFiles(File ff) {
        List<File> fileList = new ArrayList<>();
        if (ff == null || !ff.exists()) {
            return fileList;
        }
        if (ff.isFile()) {
            fileList.add(ff);
        } else if (ff.isDirectory()) {
            File[] children = ff.listFiles();
            if (children != null) {
                for (File child : children) {
                    fileList.addAll(getFiles(child));
                }
            }
        }
        return fileList;
    }
}