package com.fs.app.controller;

import com.fs.common.core.domain.AjaxResult;
import com.fs.file.domain.MiniappUploadFile;
import com.fs.file.service.IMiniappUploadService;
import com.fs.file.vo.CosPostPolicyVO;
import com.fs.file.vo.CosSTSTokenVO;
import com.fs.file.vo.UploadCompleteReqVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 小程序大文件上传 Controller
 *
 * @author fs
 */
@Slf4j
@Api(tags = "小程序文件上传")
@RestController
@RequestMapping("/app/upload")
@RequiredArgsConstructor
public class MiniappUploadController extends AppBaseController {

    private final IMiniappUploadService uploadService;

    /**
     * 获取 COS 临时密钥
     * 小程序端调用此接口获取临时密钥，然后使用临时密钥直传文件到 COS
     */
    @ApiOperation("获取COS临时密钥")
    @GetMapping("/sts-token")
    public AjaxResult getSTSToken() {
        String userId = getUserId();
        log.info("获取COS临时密钥请求, userId={}", userId);

        CosSTSTokenVO token = uploadService.getSTSToken(userId);
        return AjaxResult.success(token);
    }

    /**
     * 获取 COS POST Policy 签名
     * 前端调用此接口获取 POST Policy 签名，使用 PostObject 方式上传文件到 COS
     */
    @ApiOperation("获取COS POST Policy签名")
    @GetMapping("/post-policy")
    public AjaxResult getPostPolicy(@ApiParam("文件扩展名") @RequestParam("ext") String ext) {
        String userId = getUserId();
        log.info("获取POST Policy请求, userId={}, ext={}", userId, ext);

        CosPostPolicyVO policy = uploadService.generatePostPolicy(userId, ext);
        return AjaxResult.success(policy);
    }

    /**
     * 上传完成回调
     * 小程序上传文件到 COS 成功后，调用此接口通知后端记录文件信息
     */
    @ApiOperation("上传完成回调")
    @PostMapping("/complete")
    public AjaxResult uploadComplete(@RequestBody UploadCompleteReqVO reqVO) {
        String userId = getUserId();
        log.info("上传完成回调, userId={}, fileName={}", userId, reqVO.getFileName());

        MiniappUploadFile file = uploadService.uploadComplete(userId, reqVO);
        return AjaxResult.success("上传成功", file);
    }

    /**
     * 秒传检查
     * 小程序在上传前先计算文件 MD5，调用此接口检查文件是否已存在，实现秒传
     */
    @ApiOperation("秒传检查")
    @GetMapping("/check-fast")
    public AjaxResult checkFastUpload(@ApiParam("文件MD5") @RequestParam("md5") String md5) {
        String userId = getUserId();
        log.info("秒传检查, userId={}, md5={}", userId, md5);

        MiniappUploadFile file = uploadService.checkFastUpload(userId, md5);
        if (file != null) {
            return AjaxResult.success("文件已存在，秒传成功", file);
        }
        return AjaxResult.error("文件不存在，需要上传");
    }

    /**
     * 查询文件列表（根据业务）
     */
    @ApiOperation("查询文件列表")
    @GetMapping("/list")
    public AjaxResult listFiles(@ApiParam("业务类型") @RequestParam(value = "bizType", required = false) String bizType,
                                @ApiParam("业务ID") @RequestParam(value = "bizId", required = false) String bizId) {
        String userId = getUserId();
        log.info("查询文件列表, userId={}, bizType={}, bizId={}", userId, bizType, bizId);

        List<MiniappUploadFile> list;
        if (bizType != null && !bizType.isEmpty() && bizId != null && !bizId.isEmpty()) {
            list = uploadService.listByBiz(userId, bizType, bizId);
        } else {
            list = uploadService.listByUserId(userId);
        }

        return AjaxResult.success(list);
    }

    /**
     * 删除文件
     */
    @ApiOperation("删除文件")
    @DeleteMapping("/{id}")
    public AjaxResult deleteFile(@ApiParam("文件ID") @PathVariable Long id) {
        String userId = getUserId();
        log.info("删除文件, userId={}, fileId={}", userId, id);

        boolean success = uploadService.deleteById(userId, id);
        return success ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }

    /**
     * 批量删除文件
     */
    @ApiOperation("批量删除文件")
    @DeleteMapping("/batch")
    public AjaxResult deleteFiles(@ApiParam("文件ID列表") @RequestParam("ids") List<Long> ids) {
        String userId = getUserId();
        log.info("批量删除文件, userId={}, ids={}", userId, ids);

        boolean success = uploadService.deleteByIds(userId, ids);
        return success ? AjaxResult.success("批量删除成功") : AjaxResult.error("批量删除失败");
    }


}
