package com.ruoyi.dj.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.dj.mqtt.domain.DeleteBatchRequest;
import com.ruoyi.dj.mqtt.utils.StorageConfigUtil;
import com.ruoyi.system.domain.Missions;
import com.ruoyi.system.service.IMissionsService;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.errors.ErrorResponseException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @auther 周志雄
 * @date 2024/9/2 15:17
 */
@Slf4j
@RestController
@Api(tags = "Minio文件管理")
@RequestMapping("/minio")
public class MinioController {

    @Resource
    private IMissionsService missionsService;

    // 创建一个线程安全的 MinioClient 实例，避免重复创建
    private static final MinioClient minioClient = StorageConfigUtil.getMinioClient();

    @GetMapping("/file")
    @ApiOperation("获取文件列表")
    public String getFile(String gateway, String itemPath) throws Exception {
        // 构建存储桶名称
        String bucketName = "drone" + gateway.toLowerCase().replace("_", "").replace("-", "");

        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }

        String listDirectoryContents = StorageConfigUtil.listDirectoryContents(bucketName, itemPath);
        log.info("文件列表: {}", listDirectoryContents);
        if (listDirectoryContents == null) {
            return null;
        }
        if (itemPath == null || itemPath.equals("")) {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(listDirectoryContents);

            // 遍历所有的键
            Iterator<String> fieldNames = rootNode.fieldNames();
            while (fieldNames.hasNext()) {
                String key = fieldNames.next();
                String idStr = key.split("/")[0]; // 提取 ID
                Long id;
                try {
                    id = Long.valueOf(idStr);
                } catch (NumberFormatException e) {
                    continue;
                }
                // 获取任务名称
                Missions missions = new Missions();
                missions.setFlightId(id);
                List<Missions> missionsList = missionsService.selectMissionsList(missions);
                String missionName = idStr; // 默认使用 ID
                if (missionsList != null && !missionsList.isEmpty()) {
                    Date createdAt = missionsList.get(0).getCreatedAt();
                    missionName = missionsList.get(0).getMissionName() + "(" + new SimpleDateFormat("yyyyMMdd").format(createdAt) + ")";
                    // 在对象中添加 missionName 字段
                    JsonNode valueNode = rootNode.get(key);
                    if (valueNode instanceof ObjectNode) {
                        ((ObjectNode) valueNode).put("missionName", missionName);
                    }
                }
            }
            // 将修改后的节点转换为 JSON 字符串并返回
            return mapper.writeValueAsString(rootNode);
        }
        return listDirectoryContents;
    }


    @PostMapping("/urlList")
    @ApiOperation("获取某个目录下面的所有文件的URL列表")
    public List<String> urlList(String gateway, String itemPath) throws Exception {
        // 构建存储桶名称
        String bucketName = "drone" + gateway.toLowerCase().replace("_", "").replace("-", "");
        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }
        List<String> urlList = StorageConfigUtil.getUrlList(bucketName, itemPath);
        return urlList;
    }

    @GetMapping("/info")
    @ApiOperation("获取文件统计信息")
    public AjaxResult info(@RequestParam String gateway) throws Exception {
        // 构建存储桶名称
        String bucketName = "drone" + gateway.toLowerCase().replace("_", "").replace("-", "");
        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }
        Map<String, Object> statistics = StorageConfigUtil.getMediaStatistics(bucketName);
        return AjaxResult.success(statistics);
    }

    @DeleteMapping("/deleteBatch")
    @ApiOperation("批量删除文件")
    public AjaxResult deleteBatch(@RequestBody DeleteBatchRequest deleteBatchRequest) throws Exception {
        // 调用批量删除方法
        StorageConfigUtil.deleteFilesOrDirectories(deleteBatchRequest.getItemPaths(), deleteBatchRequest.getGateway());
        return AjaxResult.success();
    }


    @GetMapping("/ai/file")
    @ApiOperation("获取AI文件列表")
    public String getAiFile(String gateway, String itemPath) throws Exception {
        // 构建存储桶名称
        String bucketName = "ai" + gateway.toLowerCase().replace("_", "").replace("-", "");
        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }
        String listDirectoryContents = StorageConfigUtil.listDirectoryContents(bucketName, itemPath);

        if (listDirectoryContents == null) {
            return null;
        }
        if (itemPath == null || itemPath.equals("")) {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(listDirectoryContents);

            // 遍历所有的键
            Iterator<String> fieldNames = rootNode.fieldNames();
            while (fieldNames.hasNext()) {
                String key = fieldNames.next(); // 例如 "881665/"
                String idStr = key.split("/")[0]; // 提取 ID
                Long id;
                try {
                    id = Long.valueOf(idStr);
                } catch (NumberFormatException e) {
                    continue;
                }
                // 获取任务名称
                Missions missions = new Missions();
                missions.setFlightId(id);
                List<Missions> missionsList = missionsService.selectMissionsList(missions);
                String missionName = idStr; // 默认使用 ID
                if (missionsList != null && !missionsList.isEmpty()) {
                    Date createdAt = missionsList.get(0).getCreatedAt();
                    missionName = missionsList.get(0).getMissionName() + "(" + new SimpleDateFormat("yyyyMMdd").format(createdAt) + ")";
                    // 在对象中添加 missionName 字段
                    JsonNode valueNode = rootNode.get(key);
                    if (valueNode instanceof ObjectNode) {
                        ((ObjectNode) valueNode).put("missionName", missionName);
                    }
                }
            }
            // 将修改后的节点转换为 JSON 字符串并返回
            return mapper.writeValueAsString(rootNode);
        }
        return listDirectoryContents;
    }


    @PostMapping("/ai/urlList")
    @ApiOperation("获取AI检测某个目录下面的所有文件的URL列表")
    public List<String> aiUrlList(String gateway, String itemPath) throws Exception {
        // 构建存储桶名称
        String bucketName = "ai" + gateway.toLowerCase().replace("_", "").replace("-", "");
        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }
        // 调用批量下载方法
        List<String> urlList = StorageConfigUtil.getUrlList(bucketName, itemPath);
        return urlList;
    }

    @GetMapping("/ai/info")
    @ApiOperation("获取AI文件统计信息")
    public AjaxResult aiInfo(@RequestParam String gateway) throws Exception {
        // 构建存储桶名称
        String bucketName = "ai" + gateway.toLowerCase().replace("_", "").replace("-", "");
        // 检查桶是否存在，不存在则创建
        synchronized (this) {  // 使用 synchronized 避免并发创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                try {
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                    log.info("已创建桶: {}", bucketName);
                } catch (Exception e) {
                    if (e instanceof ErrorResponseException &&
                            ((ErrorResponseException) e).errorResponse().code().equals("BucketAlreadyOwnedByYou")) {
                        log.warn("桶已存在: {}", bucketName);
                    } else {
                        throw e;  // 如果是其他异常，继续抛出
                    }
                }
            }
        }
        Map<String, Object> statistics = StorageConfigUtil.getMediaStatistics(bucketName);
        return AjaxResult.success(statistics);
    }

    @DeleteMapping("/ai/deleteBatch")
    @ApiOperation("批量删除文件")
    public AjaxResult aiDeleteBatch(@RequestBody DeleteBatchRequest deleteBatchRequest) throws Exception {
        // 调用批量删除方法
        StorageConfigUtil.deleteAiFilesOrDirectories(deleteBatchRequest.getItemPaths(), deleteBatchRequest.getGateway());
        return AjaxResult.success();
    }

}
