package com.yd.oss.api.service.impl;

import com.aliyun.oss.OSS;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.auth.core.utils.SecurityUtil;
import com.yd.common.enums.CommonEnum;
import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.oss.api.service.ApiOssStsService;
import com.yd.oss.service.config.OssClientFactory;
import com.yd.oss.service.model.OssProvider;
import com.yd.oss.service.service.IOssProviderService;
import com.yd.oss.service.utils.OssUtils;
import com.yd.oss.feign.dto.ApiOssFileDto;
import com.yd.oss.feign.request.ApiBatchSaveFilesRequest;
import com.yd.oss.feign.response.ApiBatchSaveFilesResponse;
import com.yd.oss.feign.response.ApiGetStsTokenResponse;
import com.yd.oss.feign.response.ApiOssFileResponse;
import com.yd.oss.service.model.OssFile;
import com.yd.oss.service.service.IOssFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ApiOssStsServiceImpl implements ApiOssStsService {

    @Value("${aliyun.oss.role-arn:acs:ram::1164861558430519:role/oss-upload-role}")
    private String roleArn;

    // 注入最大文件大小配置，默认100MB
    @Value("${aliyun.oss.max-size:104857600}")
    private Long maxSize;

    @Autowired
    private IOssProviderService ossProviderService;

    @Autowired
    private IOssFileService iOssFileService;

    @Autowired
    private OssUtils ossUtils;

    @Autowired
    private OssClientFactory ossClientFactory; // 如果需要执行OSS操作时使用

    /**
     * 获取STS临时凭证
     * @param projectBizId 项目业务ID，用于确定使用的OSS服务商
     * @return STS凭证响应
     */
    @Override
    public Result<ApiGetStsTokenResponse> getStsToken(String projectBizId) {
        // 根据项目ID获取服务商信息
        OssProvider provider = ossProviderService.getProviderByProjectId(projectBizId);
        if (provider == null) {
            log.error("未找到项目对应的OSS服务商，projectBizId={}", projectBizId);
            return Result.fail("未找到对应的OSS服务商配置");
        }

        String region = provider.getRegion();
        String accessKeyId = provider.getAccessKey();
        String accessKeySecret = provider.getSecretKey();
        String bucket = provider.getBucketName();
        String endpoint = provider.getEndpoint();

        // 检查bucket是否存在
        // 如果需要检查，可以用ossClientFactory创建临时客户端执行操作，然后关闭
         OSS tempClient = ossClientFactory.createOssClient(provider);
         try {
             if (!tempClient.doesBucketExist(bucket)) {
                 log.warn("当前服务商的桶 {} 不存在，请确认配置", bucket);
             }
         } finally {
             tempClient.shutdown();
         }

        // 构建STS客户端
        DefaultProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        // 构建请求
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setRoleArn(roleArn);
        request.setRoleSessionName("vue-upload-session");
        request.setDurationSeconds(3600L);

        try {
            AssumeRoleResponse response = client.getAcsResponse(request);
            if (response == null || response.getCredentials() == null) {
                return Result.fail("获取STS凭证失败：返回凭证为空");
            }

            AssumeRoleResponse.Credentials credentials = response.getCredentials();

            ApiGetStsTokenResponse tokenResponse = new ApiGetStsTokenResponse();
            tokenResponse.setAccessKeyId(credentials.getAccessKeyId());
            tokenResponse.setAccessKeySecret(credentials.getAccessKeySecret());
            tokenResponse.setStsToken(credentials.getSecurityToken());
            tokenResponse.setRegion(region);
            tokenResponse.setBucket(bucket);
            tokenResponse.setEndpoint(endpoint);
            tokenResponse.setMaxSize(maxSize);

            // 获取分片文件路径的前缀
            String filePrefix = ossUtils.getShardFilePrefix(projectBizId, "");
            tokenResponse.setFilePrefix(filePrefix);
            return Result.success(tokenResponse);
        } catch (ClientException e) {
            log.error("获取STS凭证失败", e);
            return Result.fail("获取STS凭证失败: " + e.getMessage());
        }
    }

    /**
     * 批量保存文件列表（仅保存元数据，不涉及OSS操作）
     *
     * @param request 批量保存请求
     * @return 保存结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<ApiBatchSaveFilesResponse> batchSaveFiles(ApiBatchSaveFilesRequest request) {

        // 根据 projectBizId 获取服务商信息（用于填充providerBizId和bucketName）
        OssProvider provider = ossProviderService.getProviderByProjectId(request.getProjectBizId());
        if (provider == null) {
            log.error("批量保存文件时未找到服务商配置，projectBizId={}", request.getProjectBizId());
            return Result.fail("未找到对应的OSS服务商配置");
        }
        String providerBizId = provider.getProviderBizId();
        String bucketName = provider.getBucketName();

        // 获取当前登录用户信息
        AuthUserDto authUserDto = SecurityUtil.getCurrentLoginUser();
        String userId = authUserDto.getUserBizId();
        String realName = authUserDto.getRealName();

        List<OssFile> saveOssFileList = new ArrayList<>();
        List<ApiOssFileResponse> fileResponses = new ArrayList<>();

        // 遍历处理文件列表
        for (ApiOssFileDto fileDto : request.getApiOssFileDtoList()) {
            try {
                // 从完整 URL 中提取 fileKey（相对路径）
                String fileUrl = fileDto.getFileUrl();
                if (StringUtils.isBlank(fileUrl)) {
                    log.warn("文件URL为空，跳过：{}", fileDto);
                    continue;
                }
                URL url = new URL(fileUrl);
                String path = url.getPath();
                String fileKey = path.startsWith("/") ? path.substring(1) : path;

                // 生成文件业务ID
                String fileBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_OSS_FILE.getCode());

                // 获取文件类型（扩展名）
                String originalName = fileDto.getFileName();
                String fileType = FilenameUtils.getExtension(originalName);
                if (StringUtils.isBlank(fileType)) {
                    fileType = FilenameUtils.getExtension(fileKey);
                }

                // 构建实体
                OssFile file = new OssFile();
                file.setTenantBizId(request.getTenantBizId());
                file.setProjectBizId(request.getProjectBizId());
                file.setFileBizId(fileBizId);
                file.setObjectType(request.getObjectType());
                file.setObjectTableName(request.getObjectTableName());
                file.setObjectName(request.getObjectName());
                file.setObjectBizId(request.getObjectBizId());
                file.setFileKey(fileKey);
                file.setOriginalName(originalName);
                file.setFileSize(fileDto.getFileSize());
                file.setFileType(fileType);
                file.setProviderBizId(providerBizId);
                file.setBucketName(bucketName);
                file.setUploadTime(LocalDateTime.now());
                file.setUploadUser(userId);
                file.setCreatorId(userId);
                file.setCreatorName(realName);
                file.setUpdaterId(userId);
                file.setCreateTime(LocalDateTime.now());
                file.setUpdateTime(LocalDateTime.now());
                file.setIsDeleted(0);
                saveOssFileList.add(file);

                // 构建响应对象（直接使用传入的完整URL）
                ApiOssFileResponse ossFileResponse = new ApiOssFileResponse();
                ossFileResponse.setFileBizId(file.getFileBizId());
                ossFileResponse.setFileName(file.getOriginalName());
                ossFileResponse.setFileSize(file.getFileSize());
                ossFileResponse.setFileUrl(fileDto.getFileUrl()); // 设置完整URL
                fileResponses.add(ossFileResponse);

            } catch (MalformedURLException e) {
                log.error("文件URL格式错误: {}", fileDto.getFileUrl(), e);
                return Result.fail("文件URL格式错误: " + fileDto.getFileUrl());
            } catch (Exception e) {
                log.error("保存文件记录失败: {}", fileDto, e);
                return Result.fail("保存文件记录失败: " + e.getMessage());
            }
        }

        // 批量保存
        if (CollectionUtils.isNotEmpty(saveOssFileList)) {
            iOssFileService.saveOrUpdateBatch(saveOssFileList);
            // 构建响应
            ApiBatchSaveFilesResponse response = new ApiBatchSaveFilesResponse();
            response.setFileResponses(fileResponses);
            return Result.success(response);
        }
        return Result.success();
    }
}