package org.qinan.safetyeval.app.executor;

import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.qinan.safetyeval.client.co.FileInfoCO;
import org.qinan.safetyeval.domain.entity.FileStorage;
import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 文件操作公共工具类（App层内部共享）
 * <p>
 * 提供实体转换、OSS FileInfo 构建、创建人信息填充等通用逻辑。
 * </p>
 *
 * @author safety-eval
 */
final class FileStorageHelper {

    private static final Logger log = LoggerFactory.getLogger(FileStorageHelper.class);

    /** 签名URL默认过期时间：1小时（毫秒） */
    static final long PRESIGNED_URL_EXPIRE_MILLIS = Duration.ofHours(1).toMillis();

    private FileStorageHelper() {
    }

    /**
     * 根据 OSS FileInfo 构建 FileStorage 实体
     *
     * @param ossFileInfo     OSS 文件信息
     * @param originalFilename 原始文件名
     * @param isInternal      true-内部（取当前用户），false-公开（creator=system）
     */
    static FileStorage buildResource(FileInfo ossFileInfo, String originalFilename, boolean isInternal) {
        FileStorage fileStorage = new FileStorage();
        fileStorage.setUrl(ossFileInfo.getUrl());
        fileStorage.setSize(ossFileInfo.getSize());
        fileStorage.setFilename(ossFileInfo.getFilename());
        fileStorage.setOriginalFilename(originalFilename);
        fileStorage.setBasePath(ossFileInfo.getBasePath());
        fileStorage.setPath(ossFileInfo.getPath());
        fileStorage.setExt(ossFileInfo.getExt());
        fileStorage.setContentType(ossFileInfo.getContentType());
        fileStorage.setPlatform(ossFileInfo.getPlatform());
        fileStorage.setCreatedTime(LocalDateTime.now());

        if (isInternal) {
            fileStorage.setCreatorName(AuthUserContextAdapter.getCurrentUserName());
            Long userId = AuthUserContextAdapter.getCurrentUserId();
            fileStorage.setCreatorUid(userId != null ? String.valueOf(userId) : "0");
        } else {
            fileStorage.setCreatorName("system");
            fileStorage.setCreatorUid("0");
        }
        return fileStorage;
    }

    /**
     * 根据 FileStorage 实体构建 OSS FileInfo（用于存在性检查、删除、生成签名URL等OOS操作）
     */
    static FileInfo buildOssFileInfo(FileStorage fileStorage) {
        FileInfo ossFileInfo = new FileInfo();
        ossFileInfo.setUrl(fileStorage.getUrl());
        ossFileInfo.setBasePath(fileStorage.getBasePath());
        ossFileInfo.setFilename(fileStorage.getFilename());
        ossFileInfo.setPlatform(fileStorage.getPlatform());
        return ossFileInfo;
    }

    /**
     * 生成签名URL
     */
    static String generatePresignedUrl(FileStorageService fileStorageService, FileInfo ossFileInfo) {
        Date expiration = new Date(System.currentTimeMillis() + PRESIGNED_URL_EXPIRE_MILLIS);
        return fileStorageService.generatePresignedUrl(ossFileInfo, expiration).toString();
    }

    /**
     * 检查文件在 OSS 是否存在
     */
    static void checkOssExists(FileStorageService fileStorageService, FileInfo ossFileInfo) {
        if (!fileStorageService.exists(ossFileInfo)) {
            throw new BizException(ErrorCode.FILE_NOT_FOUND);
        }
    }

    /**
     * FileStorage 转 FileInfoCO
     */
    static FileInfoCO toCO(FileStorage fileStorage, String presignedUrl) {
        if (fileStorage == null) {
            return null;
        }
        FileInfoCO co = new FileInfoCO();
        co.setId(fileStorage.getId());
        co.setUrl(fileStorage.getUrl());
        co.setPresignedUrl(presignedUrl != null ? presignedUrl : fileStorage.getUrl());
        co.setSize(fileStorage.getSize());
        co.setOriginalFilename(fileStorage.getOriginalFilename());
        co.setExt(fileStorage.getExt());
        co.setContentType(fileStorage.getContentType());
        co.setCreatorName(fileStorage.getCreatorName());
        co.setCreatedTime(fileStorage.getCreatedTime());
        return co;
    }
}
