package com.dora.controller;

import com.dora.annotation.RequireAdminOrStaff;
import com.dora.common.Result;
import com.dora.dto.AdminOssUploadRequest;
import com.dora.dto.AdminOssUploadResponse;
import com.dora.service.AdminOssService;
import com.dora.util.AdminSecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.Map;

/**
 * 管理端OSS文件上传控制器
 */
@RestController
@RequestMapping("/admin/oss")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "管理端OSS文件上传", description = "管理端阿里云OSS上传相关接口")
@RequireAdminOrStaff
public class AdminOssController {

    private final AdminOssService adminOssService;

    @PostMapping("/post-signature")
    @Operation(summary = "生成管理端OSS POST签名", description = "生成管理端OSS POST签名，支持多种文件格式和更大文件大小")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "成功生成POST签名",
                    content = @Content(schema = @Schema(implementation = AdminOssUploadResponse.class))),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<AdminOssUploadResponse> generatePostSignature(
            @Valid @RequestBody AdminOssUploadRequest request) {
        try {
            // 获取当前管理员ID
            String adminId = AdminSecurityUtil.getCurrentAdminId().toString();
            
            log.info("管理员 {} 请求生成OSS上传签名: {}", adminId, request.getFileName());
            
            Map<String, Object> result = adminOssService.generateAdminPostSignature(request, adminId);
            AdminOssUploadResponse response = AdminOssUploadResponse.fromMap(result);
            
            return Result.success(response, "管理端POST签名生成成功");
        } catch (IllegalArgumentException e) {
            log.warn("管理端OSS上传参数错误: {}", e.getMessage());
            return Result.error(400, e.getMessage());
        } catch (Exception e) {
            log.error("管理端OSS上传签名生成失败: {}", e.getMessage(), e);
            return Result.error(500, "生成POST签名失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/file")
    @Operation(summary = "删除OSS文件", description = "管理员删除指定的OSS文件")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "文件删除成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<String> deleteFile(
            @Parameter(description = "对象键", required = true) @RequestParam String objectKey) {
        try {
            String adminId = AdminSecurityUtil.getCurrentAdminId().toString();
            
            log.info("管理员 {} 请求删除文件: {}", adminId, objectKey);
            
            boolean success = adminOssService.deleteAdminFile(objectKey, adminId);
            if (success) {
                return Result.success("文件删除成功");
            } else {
                return Result.error(400, "文件删除失败");
            }
        } catch (Exception e) {
            log.error("管理端删除文件失败: {}", e.getMessage(), e);
            return Result.error(500, "删除文件失败: " + e.getMessage());
        }
    }

    @PostMapping("/batch-delete")
    @Operation(summary = "批量删除OSS文件", description = "管理员批量删除多个OSS文件")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "批量删除完成",
                    content = @Content(schema = @Schema(implementation = Map.class))),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问"), 
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> batchDeleteFiles(
            @Parameter(description = "对象键列表", required = true) @RequestBody String[] objectKeys) {
        try {
            String adminId = AdminSecurityUtil.getCurrentAdminId().toString();
            
            log.info("管理员 {} 请求批量删除文件: {} 个", adminId, objectKeys.length);
            
            Map<String, Object> result = adminOssService.batchDeleteAdminFiles(objectKeys, adminId);
            return Result.success(result, "批量删除操作完成");
        } catch (Exception e) {
            log.error("管理端批量删除文件失败: {}", e.getMessage(), e);
            return Result.error(500, "批量删除文件失败: " + e.getMessage());
        }
    }

    @GetMapping("/file-info")
    @Operation(summary = "获取文件信息", description = "管理员获取OSS文件的详细信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取文件信息成功",
                    content = @Content(schema = @Schema(implementation = Map.class))),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "404", description = "文件不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public Result<Map<String, Object>> getFileInfo(
            @Parameter(description = "对象键", required = true) @RequestParam String objectKey) {
        try {
            log.info("管理员请求获取文件信息: {}", objectKey);
            
            Map<String, Object> fileInfo = adminOssService.getAdminFileInfo(objectKey);
            return Result.success(fileInfo, "获取文件信息成功");
        } catch (Exception e) {
            log.error("获取文件信息失败: {}", e.getMessage(), e);
            return Result.error(500, "获取文件信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/upload-config")
    @Operation(summary = "获取上传配置", description = "获取管理端文件上传的配置信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取配置成功",
                    content = @Content(schema = @Schema(implementation = Map.class))),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足")
    })
    public Result<Map<String, Object>> getUploadConfig() {
        try {
            Map<String, Object> config = Map.of(
                "maxFileSize", 500 * 1024 * 1024L, // 500MB
                "maxFileSizeMB", 500,
                "supportedFormats", new String[]{
                    "图片: jpg, jpeg, png, gif, bmp, webp, svg, ico, tiff",
                    "文档: pdf, txt, md, json, xml, csv, doc, docx, xls, xlsx, ppt, pptx", 
                    "压缩包: zip, rar, 7z, tar, gz, bz2, xz",
                    "音频: mp3, wav, flac, aac, ogg, wma",
                    "视频: mp4, avi, mov, wmv, flv, mkv, webm",
                    "其他: html, css, js, sql, log"
                },
                "uploadDirectories", new String[]{
                    "banners", "images", "documents", 
                    "videos", "audios", "uploads"
                },
                "tips", "管理端支持多种文件格式，最大支持500MB文件上传。文件将与用户端文件存储在同一目录下，建议根据用途选择合适的子目录。"
            );
            
            return Result.success(config, "获取上传配置成功");
        } catch (Exception e) {
            log.error("获取上传配置失败: {}", e.getMessage(), e);
            return Result.error(500, "获取上传配置失败");
        }
    }
}
