package com.haha.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.haha.common.config.OssConfig;
import com.haha.service.OssService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * OSS 对象存储服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OssServiceImpl implements OssService {

    private final OssConfig ossConfig;

    @Override
    public Map<String, String> getUploadCredential(String dir) {
        log.info("获取 OSS 上传凭证，dir: {}", dir);

        try {
            // 从 endpoint 中提取 regionId（如 oss-cn-shenzhen.aliyuncs.com -> cn-shenzhen）
            String endpoint = ossConfig.getEndpoint();
            String regionId = extractRegionId(endpoint);

            // 构造 STS 请求
            DefaultProfile profile = DefaultProfile.getProfile(
                    regionId,
                    ossConfig.getAccessKeyId(),
                    ossConfig.getAccessKeySecret()
            );
            DefaultAcsClient client = new DefaultAcsClient(profile);

            AssumeRoleRequest request = new AssumeRoleRequest();
            request.setSysMethod(MethodType.POST);
            request.setRoleArn(ossConfig.getSts().getRoleArn());
            request.setRoleSessionName(ossConfig.getSts().getRoleSessionName());
            request.setDurationSeconds(Long.valueOf(ossConfig.getSts().getDurationSeconds()));

            // 设置策略，限制只能上传到指定 bucket 和目录
            String policy = "{\n" +
                    "    \"Version\": \"1\",\n" +
                    "    \"Statement\": [\n" +
                    "        {\n" +
                    "            \"Effect\": \"Allow\",\n" +
                    "            \"Action\": [\n" +
                    "                \"oss:PutObject\",\n" +
                    "                \"oss:PostObject\"\n" +
                    "            ],\n" +
                    "            \"Resource\": [\n" +
                    "                \"acs:oss:*:*:" + ossConfig.getBucketName() + "/" + dir + "/*\"\n" +
                    "            ]\n" +
                    "        }\n" +
                    "    ]\n" +
                    "}";
            request.setPolicy(policy);

            AssumeRoleResponse response = client.getAcsResponse(request);

            // 构造返回结果
            String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String uploadDir = dir + "/" + dateDir + "/";

            Map<String, String> credential = new HashMap<>();
            credential.put("accessKeyId", response.getCredentials().getAccessKeyId());
            credential.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
            credential.put("securityToken", response.getCredentials().getSecurityToken());
            credential.put("expiration", response.getCredentials().getExpiration());
            credential.put("host", "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint());
            credential.put("dir", uploadDir);

            log.info("获取 OSS 上传凭证成功，uploadDir: {}", uploadDir);
            return credential;

        } catch (Exception e) {
            log.error("获取 OSS 上传凭证失败", e);
            throw new RuntimeException("获取上传凭证失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从 OSS endpoint 中提取 regionId
     * 例如: fuyu-catering-xxx.oss-cn-shenzhen.oss-accesspoint.aliyuncs.com -> cn-shenzhen
     */
    private String extractRegionId(String endpoint) {
        // 匹配 oss-cn-xxx 或 oss-xxx 模式
        int idx = endpoint.indexOf(".oss-");
        if (idx > 0) {
            String regionPart = endpoint.substring(idx + 5); // 跳过 ".oss-"
            int dotIdx = regionPart.indexOf('.');
            if (dotIdx > 0) {
                return regionPart.substring(0, dotIdx);
            }
            return regionPart;
        }
        // 默认 cn-hangzhou
        return "cn-hangzhou";
    }

    @Override
    public void deleteByObjectKey(String objectKey) {
        log.info("删除 OSS 文件，objectKey: {}", objectKey);

        OSS ossClient = null;
        try {
            // 创建 OSS 客户端
            String endpoint = ossConfig.getEndpoint();
            ossClient = new OSSClientBuilder().build(
                    endpoint,
                    ossConfig.getAccessKeyId(),
                    ossConfig.getAccessKeySecret()
            );

            // 删除文件
            ossClient.deleteObject(ossConfig.getBucketName(), objectKey);

            log.info("删除 OSS 文件成功，objectKey: {}", objectKey);

        } catch (Exception e) {
            log.error("删除 OSS 文件失败，objectKey: {}", objectKey, e);
            throw new RuntimeException("删除文件失败: " + e.getMessage(), e);
        } finally {
            if (ossClient != null) {
                try {
                    ossClient.shutdown();
                } catch (Exception e) {
                    log.warn("关闭 OSS 客户端失败", e);
                }
            }
        }
    }
}
