package me.qwq.doghouse.enums;

import java.util.Objects;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.baomidou.mybatisplus.annotation.EnumValue;

import me.qwq.doghouse.annotation.StaticAttribute;
import me.qwq.doghouse.entity.Asset;

/**
 * File category enum.
 **/
@StaticAttribute
public enum FileTypeEnum implements IQueryableEnum {

    OTHER(0, "其他"),
    IMAGE(1, "图片"),
    ARCHIVE(2, "压缩文件"),
    DOCUMENT(3, "文档"),
    MEDIA(4, "媒体文件"),
    APPLICATION(5, "应用程序");

    @EnumValue
    private final int status;
    private final String note;

    private static final Set<String> IMAGE_EXTENSIONS = Set.of(
            "jpg", "jpeg", "gif", "png", "apng", "bmp", "svg", "ico", "webp", "psd", "tif", "tiff", "raw", "avif");

    private static final Set<String> ARCHIVE_EXTENSIONS = Set.of(
            "zip", "rar", "7z", "001", "iso", "xz", "txz", "lzma", "tar", "cpio", "bz2", "bzip2", "tbz2", "tbz",
            "gz", "gzip", "tgz", "tpz", "z", "taz", "lzh", "lha", "rpm", "deb", "arj", "vhd", "wim", "swm", "fat",
            "ntfs", "dmg", "hfs", "xar", "squashfs");

    private static final Set<String> DOCUMENT_EXTENSIONS = Set.of(
            "doc", "docx", "dot", "dotx", "ppt", "pptx", "xls", "xlsx", "pdf", "txt", "rtf", "md");

    private static final Set<String> MEDIA_EXTENSIONS = Set.of(
            "mp3", "aac", "ac3", "amr", "ogg", "ogm", "ogv", "dts", "m1a", "m2a", "m4a", "mp2", "mpa", "mpc",
            "flac", "mid", "wav", "wma", "wmv", "mp4", "webm", "swf", "rm", "rmvb", "mov", "mpeg", "mkv", "m4b",
            "m4v", "m4p", "f4v", "flv", "3gp");

    private static final Set<String> APPLICATION_EXTENSIONS = Set.of(
            "exe", "msi", "bat", "cmd", "apk");

    private static final Set<String> UPLOAD_DENY_EXTENSIONS = Set.of(
            "bat", "cmd", "com", "cpl", "dll", "exe", "htm", "html", "hta", "jar", "js", "jsp", "msi", "php",
            "ps1", "sh", "svg", "vbs", "war", "xhtml", "xml");

    FileTypeEnum(int status, String note) {
        this.status = status;
        this.note = note;
    }

    public String getNote() {
        return note;
    }

    public int getStatus() {
        return status;
    }

    public static FileTypeEnum getFileType(Asset asset) {
        if (Objects.isNull(asset)) {
            return OTHER;
        }
        return getFileType(asset.getExt());
    }

    public static FileTypeEnum getFileType(String ext) {
        ext = normalizeExtension(ext);
        if (StringUtils.isEmpty(ext)) {
            return OTHER;
        }
        if (IMAGE_EXTENSIONS.contains(ext)) {
            return IMAGE;
        }
        if (ARCHIVE_EXTENSIONS.contains(ext)) {
            return ARCHIVE;
        }
        if (DOCUMENT_EXTENSIONS.contains(ext)) {
            return DOCUMENT;
        }
        if (MEDIA_EXTENSIONS.contains(ext)) {
            return MEDIA;
        }
        if (APPLICATION_EXTENSIONS.contains(ext)) {
            return APPLICATION;
        }
        return OTHER;
    }

    public static boolean isUploadDenied(String ext) {
        ext = normalizeExtension(ext);
        return StringUtils.isNotEmpty(ext) && UPLOAD_DENY_EXTENSIONS.contains(ext);
    }

    public static boolean isImage(String ext) {
        return getFileType(ext) == IMAGE;
    }

    public static boolean isImageCompressible(String ext) {
        ext = normalizeExtension(ext);
        return "jpg".equals(ext) || "jpeg".equals(ext) || "png".equals(ext) || "gif".equals(ext);
    }

    public static String normalizeExtension(String ext) {
        if (StringUtils.isBlank(ext)) {
            return "";
        }
        ext = ext.trim().toLowerCase();
        return ext.startsWith(".") ? ext.substring(1) : ext;
    }
}
