package com.zhengmeng.ocrplatform.document;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HexFormat;

@Service
public class LocalDocumentStorageService implements DocumentStorageService {
    private static final DateTimeFormatter DATE_PATH = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    private final StorageProperties properties;

    public LocalDocumentStorageService(StorageProperties properties) {
        this.properties = properties;
    }

    @Override
    public StoredDocument store(String taskId, MultipartFile file) {
        String filename = sanitizeFilename(file.getOriginalFilename());
        Path relativePath = Path.of(DATE_PATH.format(LocalDate.now()), taskId, filename);
        Path target = properties.rootPath().resolve(relativePath).normalize();

        try {
            Files.createDirectories(target.getParent());
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            try (InputStream input = new DigestInputStream(file.getInputStream(), digest)) {
                Files.copy(input, target);
            }
            return new StoredDocument(
                    filename,
                    relativePath.toString(),
                    file.getContentType(),
                    file.getSize(),
                    HexFormat.of().formatHex(digest.digest())
            );
        } catch (IOException | NoSuchAlgorithmException ex) {
            throw new DocumentStorageException("Failed to store uploaded OCR document", ex);
        }
    }

    @Override
    public Path resolve(String objectPath) {
        return properties.rootPath().resolve(objectPath).normalize();
    }

    private String sanitizeFilename(String originalFilename) {
        String candidate = StringUtils.hasText(originalFilename) ? originalFilename : "upload.bin";
        return candidate.replaceAll("[\\\\/:*?\"<>|\\p{Cntrl}]+", "_");
    }
}
