package com.competition.modules.oss.service;

import com.competition.modules.oss.config.OssConfig;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class OssService {

    private final OssConfig ossConfig;

    /**
     * 上传文件，优先使用腾讯云 COS，未配置时降级到本地存储
     */
    public String uploadFile(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String ext = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String uniqueName = UUID.randomUUID().toString().replace("-", "") + ext;
        String key = datePath + "/" + uniqueName;

        if (StringUtils.hasText(ossConfig.getSecretId())) {
            return uploadToCos(file, key);
        } else {
            return uploadToLocal(file, key);
        }
    }

    private String uploadToCos(MultipartFile file, String key) {
        COSCredentials cred = new BasicCOSCredentials(ossConfig.getSecretId(), ossConfig.getSecretKey());
        ClientConfig clientConfig = new ClientConfig(new Region(ossConfig.getRegion()));
        COSClient cosClient = new COSClient(cred, clientConfig);

        try {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());

            PutObjectRequest putRequest = new PutObjectRequest(
                    ossConfig.getBucket(), key, file.getInputStream(), metadata);
            cosClient.putObject(putRequest);

            String url;
            if (StringUtils.hasText(ossConfig.getUrlPrefix())) {
                url = ossConfig.getUrlPrefix().replaceAll("/$", "") + "/" + key;
            } else {
                url = "https://" + ossConfig.getBucket() + ".cos." + ossConfig.getRegion() + ".myqcloud.com/" + key;
            }

            log.info("文件上传至 COS 成功: {}", url);
            return url;
        } catch (IOException e) {
            log.error("文件上传至 COS 失败", e);
            throw new RuntimeException("文件上传失败", e);
        } finally {
            cosClient.shutdown();
        }
    }

    private String uploadToLocal(MultipartFile file, String key) {
        try {
            Path basePath = Paths.get(System.getProperty("user.dir"), "uploads");
            Path filePath = basePath.resolve(key);
            Files.createDirectories(filePath.getParent());
            file.transferTo(filePath.toAbsolutePath().toFile());

            String url = "/uploads/" + key;
            log.info("文件上传至本地成功: {}", filePath.toAbsolutePath());
            return url;
        } catch (IOException e) {
            log.error("文件上传至本地失败", e);
            throw new RuntimeException("文件上传失败", e);
        }
    }
}
