package com.zg.common.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 本地图片保存工具
 * - 根目录：photo.root（默认 D:\photo）
 * - 目录结构：{documentType}/yyyy-MM-dd/
 * - 文件命名：
 *   入库：billNo_gysMc_yyyyMMddHHmmssSSS_index.ext
 *   出库：billNo_xmMs_yyyyMMddHHmmssSSS_index.ext
 */
@Component
public class LocalPhotoUtil {

    @Value("${photo.root:D:\\\\photo}")
    private String rootPath;

    private static final String ILLEGAL_CHARS = "\\/:*?\"<>|";

    /** yyyy-MM-dd（目录） */
    private String today() {
        return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    }

    /** yyyyMMddHHmmssSSS（文件戳） */
    private String nowStamp() {
        return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
    }

    /**
     * 生成基础名：
     *  - 入库(photoType=0)：billNo_gysMc
     *  - 出库(photoType=1)：billNo_xmMs
     *  - 若为空 → 一律替换成 "无"
     */
    public String buildBaseName(String photoType, String billNo, String xmMs, String gysMc) {
        String safeBillNo = sanitize(defaultString(billNo));
        String part;
        if ("0".equals(photoType)) {
            part = sanitize(defaultString(gysMc, "无"));
        } else {
            part = sanitize(defaultString(xmMs, "无"));
        }
        return sanitize(safeBillNo + "_" + part);
    }

    /**
     * 保存单个文件
     * @param file     文件
     * @param subDir   一级子目录（documentType）
     * @param baseName 基础名
     * @param index    序号
     */
    public SaveResult saveOne(MultipartFile file, String subDir, String baseName, int index) throws Exception {
        String ext = resolveExt(file);
        String safeSub = sanitize(defaultString(subDir, ""));
        String dirPart = safeSub + File.separator + today() + File.separator;

        String stamp = nowStamp();
        String safeBase = sanitize(baseName);
        String fileName = safeBase + "_" + stamp + "_" + index + ext;

        File dir = new File(rootPath, dirPart);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new RuntimeException("创建目录失败：" + dir.getAbsolutePath());
        }

        File dest = new File(dir, fileName);
        try (InputStream in = file.getInputStream()) {
            Files.copy(in, dest.toPath());
        }

        SaveResult r = new SaveResult();
        r.setWebPath((dirPart + fileName).replace("\\", "/"));
        r.setFileName(fileName);
        return r;
    }

    /**
     * 批量保存
     */
    public List<SaveResult> saveBatch(List<MultipartFile> files, String subDir, String baseName) throws Exception {
        if (files == null || files.isEmpty()) {
            return Collections.emptyList();
        }
        List<SaveResult> list = new ArrayList<>(files.size());
        for (int i = 0; i < files.size(); i++) {
            list.add(saveOne(files.get(i), subDir, baseName, i + 1));
        }
        return list;
    }

    /** 解析扩展名 */
    private String resolveExt(MultipartFile file) {
        String origin = file.getOriginalFilename();
        if (origin != null) {
            int dot = origin.lastIndexOf('.');
            if (dot >= 0) {
                String ext = origin.substring(dot);
                if (ext.length() <= 10) {
                    return ext;
                }
            }
        }
        String ct = file.getContentType();
        if ("image/png".equalsIgnoreCase(ct)) return ".png";
        if ("image/jpeg".equalsIgnoreCase(ct) || "image/jpg".equalsIgnoreCase(ct)) return ".jpg";
        return ".bin";
    }

    /** 清洗文件名 */
    public String sanitize(String name) {
        if (name == null) return "unnamed";
        String t = name.trim().replaceAll("\\s+", " ");
        StringBuilder sb = new StringBuilder(t.length());
        for (int i = 0; i < t.length(); i++) {
            char c = t.charAt(i);
            sb.append(ILLEGAL_CHARS.indexOf(c) >= 0 ? '_' : c);
        }
        String out = sb.toString();
        String upper = out.toUpperCase(Locale.ROOT);
        if (upper.matches("CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9]")) {
            out = "_" + out;
        }
        if (out.length() > 100) {
            out = out.substring(0, 100);
        }
        return out;
    }

    private String defaultString(String s) {
        return s == null ? "" : s;
    }
    private String defaultString(String s, String def) {
        return (s == null || s.isEmpty()) ? def : s;
    }

    /** 返回值对象 */
    public static class SaveResult {
        private String webPath;
        private String fileName;
        public String getWebPath() { return webPath; }
        public void setWebPath(String webPath) { this.webPath = webPath; }
        public String getFileName() { return fileName; }
        public void setFileName(String fileName) { this.fileName = fileName; }
    }
}
