package me.qwq.doghouse;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import jodd.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import me.qwq.doghouse.config.DoghouseProperties;
import me.qwq.doghouse.entity.Asset;
import me.qwq.doghouse.entity.Post;
import me.qwq.doghouse.enums.FileTypeEnum;
import me.qwq.doghouse.service.AssetService;
import me.qwq.doghouse.service.post.PostService;

@SpringBootTest
@Slf4j
public class ImageSizeTest {
    
    @Autowired
    AssetService assetService;
    
    @Autowired
    PostService postService;
    
    @Autowired
    DoghouseProperties doghouseProperties;
    
    //@Test
    public void testImageSize() {
        List<Asset> assets = assetService.list(
                new LambdaQueryWrapper<Asset>()
                .eq(Asset::getFileType, FileTypeEnum.IMAGE));
        for (Asset asset : assets)
            try {
                File file = new File(doghouseProperties.getFileUploadPath(asset));
                BufferedImage image = ImageIO.read(file);
                if (image == null) {
                    log.warn("{} is null", asset.getPath());
                    continue;
                }
                int width = image.getWidth();
                int height = image.getHeight();
                log.info("{} - w: {}, h: {}",
                        asset.getTitle(), width, height);
                asset.setImageHeight(height).setImageWidth(width).updateById();
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
            }
    }
    
    @Test
    public void updateNewImageFormat() {

        List<Asset> assets = assetService.list(
                new LambdaQueryWrapper<Asset>()
                .eq(Asset::getFileType, FileTypeEnum.IMAGE));
        
        List<Post> posts = postService.list();
        for (Asset asset : assets) {
            String realPath = doghouseProperties.getFileUploadPath(asset);
            String originalPath = asset.getPath();
            File file = FileUtil.file(realPath);
            if (file == null) {
                log.info("File {} does not exist", realPath);
            }
            String suffix = getSuffix(realPath);
            
            if (suffix.equals("avif") || suffix.equals("webp")) continue;
            
            // 获取可能存在的 avif 和 webp 文件
            String fullPrefix = realPath.substring(0, realPath.lastIndexOf('.'));
            String avifPath = fullPrefix + ".avif";
            String webpPath = fullPrefix + ".webp";
            
            File avifFile = FileUtil.file(avifPath);
            File webpFile = FileUtil.file(webpPath);
            String finalPath = null;
            File finalFile = null;
            
            if (avifFile.exists() && webpFile.exists()) {
                // 比较两者大小
                if (avifFile.length() < webpFile.length()) {
                    finalPath = avifPath;
                    finalFile = avifFile;
                    webpFile.deleteOnExit();
                }
                else {
                    finalPath = webpPath;
                    finalFile = webpFile;
                    avifFile.deleteOnExit();
                }
                log.info("{}[{}], {}[{}], choose {}", avifFile.getName(), avifFile.length()
                        , webpFile.getName(), webpFile.length(), finalPath);
            }
            else if (avifFile.exists()) {
                finalPath = avifPath;
                finalFile = avifFile;
                log.info("Avif found only, choose {}", avifFile.getName());
            }
            else if (webpFile.exists()) {
                finalPath = webpPath;
                finalFile = webpFile;
                log.info("Webp found only, choose {}", webpFile.getName());
            }
            
            if (finalPath == null) {
                log.info("Not replacement found for {}", file.getName());
                continue;
            }
            
            finalPath = doghouseProperties.getFileSqlPath(finalPath);
            file.delete();
            // 将 Asset 路径替换为 finalPath 路径
            asset.setPath(finalPath).setFileSize(finalFile.length()).updateById();
            
            // 递归 Post，发现能替换的直接替换并更新
            for (Post post : posts) {
                String postContent = post.getPostContent();
                String postPreface = post.getPostPreface();
                postContent = postContent.replace(originalPath, finalPath);
                if (postPreface != null) {
                    postPreface = postPreface.replace(originalPath, finalPath);
                    post.setPostPreface(postPreface);
                }
                post.setPostContent(postContent);
            }
        }
        for (Post post : posts) {
            post.updateById();
        }
    }
    
    //@Test
    public void findUnexistedInDatabase() throws IOException {
        String directoryPath = "D:\\tmp\\myblog\\upload"; // 指定目录的路径
        String[] fileExtensions = {".png", ".jpg"}; // 指定文件后缀名数组

        List<File> files = findFiles(directoryPath, fileExtensions);

        if (files.isEmpty()) {
            System.out.println("No files found.");
        } else {
            // 倒序输出，插入数据库
            System.out.println("Found files:");
            
            long j = 49;
            
            for (int i = files.size() - 1; i >= 0; i--) {
                File file = files.get(i);
                System.out.println(file.getAbsolutePath());
                
                // 先插入，后面再慢慢调 title 吧
                Asset asset = new Asset();
                
                BufferedImage image = ImageIO.read(file);

                asset.setImageHeight(image.getHeight())
                     .setImageWidth(image.getWidth());
                
                Post post = postService.getOne(new LambdaQueryWrapper<Post>()
                        .like(Post::getPostContent, file.getName())
                        .or()
                        .like(Post::getPostPreface, file.getName())
                        );
                
                LocalDateTime fileModified = Instant.ofEpochMilli(file.lastModified())
                        .atZone(ZoneId.systemDefault())
                        .toLocalDateTime();
                
                asset
                    .setAssetId(j--)
                    .setFromPostId(post.getPostId()) // 后续配置
                    .setTitle(file.getName())
                    .setCreateTime(fileModified)
                    .setFileType(FileTypeEnum.IMAGE)
                    .setFileSize(file.length())
                    .setUpdateTime(fileModified)
                    .setPath(Paths.get(doghouseProperties.getFileSqlPath(), file.getName())
                            .toString().replace('\\', '/'));
                
                assetService.saveOrUpdate(asset);
                
            }
        }
    }
    
    public static List<File> findFiles(String directoryPath, String[] fileExtensions) {
        List<File> result = new ArrayList<>();
        File directory = new File(directoryPath);

        // 检查目录是否存在
        if (!directory.exists()) {
            System.out.println("Directory does not exist.");
            return result;
        }

        // 递归查找文件
        findFilesRecursive(directory, fileExtensions, result);

        return result;
    }

    private static void findFilesRecursive(File directory, String[] fileExtensions, List<File> result) {
        // 获取目录中的所有文件和子目录
        File[] fileList = directory.listFiles();

        if (fileList != null) {
            for (File file : fileList) {
                if (file.isDirectory()) {
                    // 如果是子目录，递归调用
                    findFilesRecursive(file, fileExtensions, result);
                } else {
                    // 如果是文件，检查文件名是否以指定后缀结尾
                    for (String extension : fileExtensions) {
                        if (file.getName().toLowerCase().endsWith(extension)) {
                            result.add(file);
                            break; // 找到一个匹配后缀就可以了，跳出循环
                        }
                    }
                }
            }
        }
    }
    
    public static String getSuffix(String filename){
        if (StringUtils.isEmpty(filename)) {
            return null;
        }
        int lastIndexOfDot = filename.lastIndexOf('.');
        if (lastIndexOfDot == -1 || lastIndexOfDot == filename.length() - 1) {
            return "";
        }
        return filename.substring(lastIndexOfDot + 1).toLowerCase();
    }
}
