package com.bcxin.backend.domain.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.bcxin.backend.domain.utils.ftp.FtpConnection;
import com.bcxin.backend.domain.utils.ftp.FtpFactory;
import org.apache.commons.io.IOUtils;

import javax.imageio.stream.FileImageInputStream;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 有关文件处理的工具类
 * @author       liandi
 * @see          [相关类，可选、也可多条，对于重要的类或接口建议注释]
 * @since        esign, 2017年10月24日
 */
public final class FileUtils
{
    private FileUtils()
    {
        
    }
    
    /**
     * 创建目录，如果目录已经存在，则将会返回false
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param file
     * @return 
     */
    public static boolean mkdirs(File file)
    {
        if(null == file) return false;
        
        if(file.exists()) return false;
        
        return file.mkdirs();
    }
    
    /**
     * 创建目录，如果目录已经存在，则将会返回false
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param directory
     * @return
     */
    public static boolean mkdirs(String directory)
    {
        if(StringUtils.isBlank(directory)) return false;
        
        return mkdirs(new File(directory));
    }
    
    /**
     * 删除文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param file
     * @return
     */
    public static boolean delete(File file)
    {
        if(null == file) return false;
        
        if(!file.exists()) return false;
        
        return file.delete();
    }
    
    /**
     * 删除文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param file
     * @return
     */
    public static boolean delete(String file)
    {
        if(StringUtils.isBlank(file)) return false;
        
        return delete(new File(file));
    }
    
    /**
     * 文件是否存在
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年12月18日
     * @param fileName   文件的绝对路径
     * @return
     */
    public static boolean exists(String fileName)
    {
        if (StringUtils.isBlank(fileName)) return false;
        
        File file = new File(fileName);
        
        return file.exists();
    }
    
    /**
     * 获取文件头信息
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param file   文件路径 
     * @return
     */
    public static String getFileHeader(String file)
    {
        InputStream in = null;
        try
        {
            in = new FileInputStream(file);
            byte[] header = new byte[4];
            in.read(header, 0, header.length);
            
            return StringUtils.bytes2Hex(header);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if(null != in)
                {
                    in.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        
        return null;
    }
    
    /**
     * 获取文件头信息
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param fileData   文件数据
     * @return
     */
    public static String getFileHeader(byte[] fileData)
    {
        if(null == fileData) return null;
        
        byte[] header = new byte[4];
        
        System.arraycopy(fileData, 0, header, 0, header.length);
        
        return StringUtils.bytes2Hex(header);
    }
    
    /**
     * 判断文件是否为bmp文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param fileData   文件数据
     * @return
     */
    public static boolean isBmpFile(byte[] fileData)
    {
        if(null == fileData) return false;
        
        String header = getFileHeader(fileData).toUpperCase(Locale.ENGLISH);
        header = header.substring(0,4);
        
        return "424D".equals(header);
    }
    
    /**
     * 判断文件是否为pdf文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param fileData   文件数据
     * @return
     */
    public static boolean isPdfFile(byte[] fileData)
    {
        if(null == fileData) return false;
        
        String header = getFileHeader(fileData).toUpperCase(Locale.ENGLISH);
        header = header.substring(0,4);
        
        return "2550".equals(header);
    }
    
    public static boolean isPdfFile(String filePath)
    {
        if(StringUtils.isBlank(filePath)) return false;
        
        String header = getFileHeader(filePath).toUpperCase(Locale.ENGLISH);
        header = header.substring(0,4);
        
        return "2550".equals(header);
    }
    /**
     * 判断文件是否为word excel文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param fileData   文件数据
     * @return
     */
    public static boolean isWordOrExcel(byte[] fileData)
    {
        if(null == fileData) return false;
        
        String header = getFileHeader(fileData).toUpperCase(Locale.ENGLISH);
        header = header.substring(0,4);
        
        return "D0CF".equals(header);
    }
    
    /**
     * 判断文件是否为pfx文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年11月16日
     * @param fileData    文件数据
     * @return
     */
    public static boolean isPfxFile(byte[] fileData)
    {
        if(null == fileData) return false;
        
        String header = getFileHeader(fileData).toUpperCase(Locale.ENGLISH);
        header = header.substring(0,4);
        
        return "3082".equals(header);
    }
    
    
    /**
     * 通过文件名获取文件的扩展名
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2017年10月24日
     * @param fileName
     * @return
     */
    public static String getExpandedNameByFileName(String fileName)
    {
        if(StringUtils.isBlank(fileName)) return null;
        
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

	public byte[] image2byte(String path) {
		byte[] data = null;
		FileImageInputStream input = null;
		try {
			input = new FileImageInputStream(new File(path));
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int numBytesRead = 0;
			while ((numBytesRead = input.read(buf)) != -1) {
				output.write(buf, 0, numBytesRead);
			}
			data = output.toByteArray();
			output.close();
			input.close();
		} catch (FileNotFoundException ex1) {
     	   ex1.printStackTrace();
		} catch (IOException ex1) {
			ex1.printStackTrace();
		}
		return data;
	}
	
	public static byte[] readInputStreamToBytes(InputStream in) throws IOException
    {
        if(null == in)
        {
            return null;
        }
        
        ByteArrayOutputStream out = null;
        try
        {
            out = new ByteArrayOutputStream(4096);
            
            byte[] data = new byte[4096];
            int len = 0;
            while((len = in.read(data)) > 0)
            {
                out.write(data,0,len);
                
            }
            
            return out.toByteArray();
        }
        finally
        {
            IOUtils.closeQuietly(out);
        }
    }
	/**
     * 将文件内容读取成二进制
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2018年1月9日
     * @param filePath    文件的绝对路径
     * @return
     */
    public static byte[] readFileTobytes(String filePath)
    {
        InputStream in = null;
        
        try
        {
            in = new FileInputStream(filePath);
            return IOUtils.toByteArray(in);
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (null != in)
                {
                    in.close();
                }
            }
            catch (IOException e)
            {
               e.printStackTrace();
            }
        }
        
        return null;
    }
    /**
     * 将二进制数据写入一个文件
     * @author       liandi
     * @see          相关函数，对于重要的函数建议注释
     * @since        esign, 2018年1月9日
     * @param data
     * @param filePath
     */
    public static void write(byte[] data, String filePath)
    {
        OutputStream out = null;
        try
        {
            out = new FileOutputStream(filePath);
            IOUtils.write(data, out);
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (null != out)
                {
                    out.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    public static boolean copyFile(String srcFileName, String destFileName,boolean overlay) {
		File srcFile = new File(srcFileName);
		if (!srcFile.exists()) {
			return false;
		} 
		if (!srcFile.isFile()) {
			return false;
		}
		File destFile = new File(destFileName);
		if (destFile.exists()) {
			if (overlay) {
				new File(destFileName).delete();
			}
		} else if (!destFile.getParentFile().exists()){
			if (!destFile.getParentFile().mkdirs()) {
				return false;
			}
		}
		int byteread = 0;  
		InputStream in = null;
		OutputStream out = null;

		try {
			in = new FileInputStream(srcFile);
			out = new FileOutputStream(destFile);
			byte[] buffer = new byte[1024];

			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			buffer=null;
			return true;
		} catch (FileNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		} finally {
			try {
				if (out != null)
					out.close();
				if (in != null)
					in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


    /**
     * <b> 获取ftp目录下所有最近5分钟内生成的文件的文件名，返回文件名列表 </b>
     * @author ZXF
     * @create 2024/11/27 0027 8:44
     * @version
     * @注意事项 </b>
     */
    public static List<File> filenames(String path, String keywork) {
        try {
            File folder = new File(path);
//            List<String> recentFiles = new ArrayList<>();
            long currentTime = System.currentTimeMillis();
            long fiveMinutesAgo = currentTime - (5 * 60 * 1000); // 5 minutes ago in milliseconds
            return FileUtil.loopFiles(folder, new FileFilter() {
                        @Override
                        public boolean accept(File file) {
                            //检索修改时间在5分钟内，并且文件名开头为OUT|
                            if (file.isFile() && file.lastModified() >= fiveMinutesAgo) {
                                if (StringUtils.isEmpty(keywork) || file.getName().startsWith(keywork)) {
                                    return true;
                                }
                            }
                            return false;
                        }
                    });
        } catch (Exception e) {
            System.err.println("=======>获取目录下所有最近5分钟内生成的文件的文件名："+e.getMessage()+"<=======");
        }
        return new ArrayList<>();
    }

    public static void delLastDayFile(String path, String keywork) {
        try {
            File folder = new File(path);
            long currentTime = System.currentTimeMillis();
            long fiveMinutesAgo = currentTime - (12 * 60 * 60 * 1000); // 12小时前
            List<File> list =  FileUtil.loopFiles(folder, new FileFilter() {
                @Override
                public boolean accept(File file) {
                    //检索修改时间小于12小时前，并且文件名开头为OUT|
                    if (file.isFile() && file.lastModified() <= fiveMinutesAgo) {
                        if (StringUtils.isNotEmpty(keywork) && file.getName().startsWith(keywork)) {
                            return true;
                        }
                    }
                    return false;
                }
            });
            for (File file : list){
                delete(file);
            }
        } catch (Exception e) {
            System.err.println("=======>获取目录下12小时前产生文件做删除业务出现异常："+e.getMessage()+"<=======");
        }
    }

    //使用hutool 文件工具类 实现传入文件路径和文件名、文件文本内容 生成文件
    public static void writeFile(String filePath, String fileName, String content) {
        File file = new File(filePath + File.separator + fileName);
        if (!file.exists()) {
            FileUtil.touch(file);
        }
        FileUtil.writeString(content, file, "UTF-8");
    }

    /**
     * <b> 远程地址转base64 </b>
     * @author ZXF
     * @create 2025/01/08 0008 15:18
     * @version
     * @注意事项 </b>
     */
    public static String urlToBase64(String url) {
        // 使用Java的IO流来读取远程文件内容
        try (InputStream inputStream = new URL(url).openStream()) {
            // 读取文件内容
            byte[] bytes = IoUtil.readBytes(inputStream);
            // 转换为 Base64 字符串
            return Base64.encode(bytes);
        }catch (Exception e){
            System.err.println("=======>远程地址转base64异常.urlToBase64，err："+e.getMessage()+"<=======");
//            e.printStackTrace();
        }
        return "";
    }

    public static String fileToBase64(String filePath) {
        try (InputStream inputStream = new FileInputStream(filePath)) {
            // 读取文件内容
            byte[] bytes = IOUtils.toByteArray(inputStream);
            // 转换为 Base64 字符串
            return Base64.encode(bytes);
        }catch (Exception e){
            System.err.println("=======>服务器地址转base64异常.fileToBase64，err："+e.getMessage()+"<=======");
        }
        return "";
    }

    public static void main(String[] args) {
        String a = "C:\\Users\\Administrator\\Downloads\\BBEJ13037125QAAA75PZ.pdf";
        System.out.println(fileToBase64(a));
    }
}
