package com.ruoyi.common.utils.file;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.RuoYiConfig;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

/**
 * 文件处理工具类
 *
 * @author ruoyi
 */
public class FileUtils extends org.apache.commons.io.FileUtils
{
    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";

    /**
     * 输出指定文件的byte数组
     *
     * @param filePath 文件路径
     * @param os 输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException
    {
        FileInputStream fis = null;
        try
        {
            File file = new File(filePath);
            if (!file.exists())
            {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0)
            {
                os.write(b, 0, length);
            }
        }
        catch (IOException e)
        {
            throw e;
        }
        finally
        {
            if (os != null)
            {
                try
                {
                    os.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (fis != null)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     *
     * @param filePath 文件
     * @return
     */
    public static boolean deleteFile(String filePath)
    {
        boolean flag = false;
        File file = new File(filePath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists())
        {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 文件名称验证
     *
     * @param filename 文件名称
     * @return true 正常 false 非法
     */
    public static boolean isValidFilename(String filename)
    {
        return filename.matches(FILENAME_PATTERN);
    }

    /**
     * 文件名称验证并替换
     *
     * @param filename 文件名称
     * @return true 正常 false 非法
     */
    public static String isValidFilenameAndReplace(String filename)
    {
        if (filename.matches(FILENAME_PATTERN)) {
            return filename;
        } else {
            return filename.replaceAll("[^a-zA-Z0-9_-|.\\u4e00-\\u9fa5]", "_");
        }
    }

    /**
     * 下载文件名重新编码
     *
     * @param request 请求对象
     * @param fileName 文件名
     * @return 编码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
            throws UnsupportedEncodingException
    {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE"))
        {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        }
        else if (agent.contains("Firefox"))
        {
            // 火狐浏览器
            filename = new String(fileName.getBytes(), "ISO8859-1");
        }
        else if (agent.contains("Chrome"))
        {
            // google浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        else
        {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    /**
     * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
     *
     * @param fileName 路径名称
     * @return 没有文件路径的名称
     */
    public static String getName(String fileName)
    {
        if (fileName == null)
        {
            return null;
        }
        int lastUnixPos = fileName.lastIndexOf('/');
        int lastWindowsPos = fileName.lastIndexOf('\\');
        int index = Math.max(lastUnixPos, lastWindowsPos);
        return fileName.substring(index + 1);
    }


    /**
     * @param
     * @return 映射签名的文件名
     * @throws IOException
     */
    public static String fileName(String filepath) {
        if (StringUtils.isEmpty(filepath)){
            filepath = "/profile/uploadPath/userSign/暂无签名.jpg";
        }
        String newFilePath = filepath.replace("/profile", "");
        String pathName = RuoYiConfig.getProfile() + newFilePath;
        if (!new File(pathName).exists()) {
            genSignImage(pathName);
        }
        return pathName;
    }

    public static void genSignImage(String pathName) {
        String nickName = pathName.substring(pathName.lastIndexOf("/") + 1, pathName.lastIndexOf("."));
        String fileType = pathName.substring(pathName.lastIndexOf(".") + 1);
        int width = 350; // 图片宽度
        int height = 100; // 图片高度

        // 创建一个类型为预定义图像类型之一的 BufferedImage
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取 Graphics2D
        Graphics2D g2d = image.createGraphics();

        // 设置背景颜色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        // 设置字体和颜色
        g2d.setFont(new Font("楷体", Font.BOLD, 80)); // 设置字体样式、大小和类型
        g2d.setColor(Color.BLACK); // 设置文字颜色

        // 计算文本的宽度和高度，用于定位
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(nickName);
        int textHeight = fm.getHeight();

        // 在图片上绘制文本
        // 注意：x和y坐标定义了文本左下角的位置
        int x = (width - textWidth) / 2; // 居中显示
        int y = height - textHeight + 70; // 距离底部10像素
        g2d.drawString(nickName, x, y);

        // 释放图形上下文使用的系统资源
        g2d.dispose();

        // 保存图片到文件
        try {
            String path = pathName.substring(0, pathName.lastIndexOf("/"));
            if (!new File(path).isDirectory()) {
                new File(path).mkdirs();
            }
            OutputStream out = Files.newOutputStream(Paths.get(pathName));
            ImageIO.write(image, fileType, out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
