package com.backendsys.modules.upload.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.backendsys.exception.CustException;
import com.backendsys.modules.common.aspect.SysLog;
import com.backendsys.modules.common.config.security.enums.SecurityEnum;
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
import com.backendsys.modules.common.config.security.utils.SecurityUtil;
import com.backendsys.modules.common.enums.MatchType;
import com.backendsys.modules.common.utils.Result;
import com.backendsys.modules.upload.entity.SysFile;
import com.backendsys.modules.upload.entity.SysFileMergeByMd5;
import com.backendsys.modules.upload.service.SysFileService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Validated
@RestController
@Tag(name = "文件管理")
public class SysFileController {

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private SysFileService sysFileService;

    /**
     * 获取上传文件列表
     * - 缩略图 (?imageView2/1/w/100/h/100/q/60)
     */
    @Operation(summary = "获取文件列表 (全权限)")
    @PreAuthorize("@sr.hasPermission('1.1.1')")
    @GetMapping("/api/upload/getUploadFileAllList")
    public Result getUploadFileAllList(@Validated SysFile sysFile) {
        return Result.success().put("data", sysFileService.selectUploadFileList(sysFile));
    }

    @Operation(summary = "获取文件列表 (我的)")
    @PreAuthorize("@sr.hasPermission('1.1.2')")
    @GetMapping("/api/upload/getUploadFileList")
    public Result getUploadFileList(@Validated SysFile sysFile) {
        sysFile.setUser_id(SecurityUtil.getUserId());
        return Result.success().put("data", sysFileService.selectUploadFileList(sysFile));
    }

    @Operation(summary = "查看当前上传存储介质")
    @PreAuthorize("@sr.hasPermission('1.1.2')")
    @GetMapping("/api/upload/getUploadTarget")
    public Result getUploadTarget(@Validated SysFile sysFile) {
        return Result.success().put("data", sysFileService.selectUploadTarget());
    }

    @SysLog("上传文件 (普通上传)")
    @Operation(summary = "上传文件 (普通上传，单文件上传不超过 100MB)")
    @PreAuthorize("@sr.hasPermission('1.1.3')")
    @PostMapping("/api/upload/uploadSmall")
    public Result uploadSmall(@RequestParam("file") MultipartFile multipartFile, Long category_id, Integer is_watermark) {
        return Result.success().put("data", sysFileService.uploadSmall(multipartFile, category_id, is_watermark));
    }

    @SysLog("编辑文件")
    @Operation(summary = "编辑文件")
    @PreAuthorize("@sr.hasPermission('1.1.4')")
    @PutMapping("/api/upload/updateUploadFile")
    public Result updateUploadFile(@Validated(SysFile.Update.class) @RequestBody SysFile sysFile) {
        sysFile.setUser_id(SecurityUtil.getUserId());
        return Result.success().put("data", sysFileService.updateUploadFile(sysFile));
    }

    @SysLog("编辑文件 (批量)")
    @Operation(summary = "编辑文件 (批量)")
    @PreAuthorize("@sr.hasPermission('1.1.4')")
    @PutMapping("/api/upload/updateUploadFileBatch")
    public Result updateUploadFileBatch(@Validated(SysFile.UpdateBatch.class) @RequestBody SysFile sysFile) {
        sysFile.setUser_id(SecurityUtil.getUserId());
        return Result.success().put("data", sysFileService.updateUploadFileBatch(sysFile));
    }

    @SysLog("删除文件")
    @Operation(summary = "删除文件")
    @DeleteMapping("/api/upload/removeUploadFile")
    public Result removeUploadFile(@Validated(SysFile.Delete.class) @RequestBody SysFile sysFile) {

        // 判断是否存在
        String object_key = sysFile.getObject_key();
        SysFile querySysFile = sysFileService.getOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getObject_key, object_key));
        if (querySysFile == null) throw new CustException("文件不存在");

        // 是否 [文件] 拥有者，权限：
        // - 删除自己的 (需 1.1.6 权限)
        // - 删除自己及他人的 (需要 1.1.5 权限或超级管理员)
        Boolean isOwner = querySysFile.getUser_id() == SecurityUtil.getUserId();
        if (isOwner && !securityUtil.hasPermissions(Arrays.asList("1.1.5", "1.1.6"), MatchType.OR)) {
            throw new CustException(SecurityEnum.NOAUTH);
        }
        if (!isOwner && !securityUtil.hasPermission("1.1.5")) {
            throw new CustException(SecurityEnum.NOAUTH);
        }
        // ---------------------------------------------------------------------------

        return Result.success().put("data", sysFileService.removeUploadFile(sysFile, querySysFile));
    }

    @SysLog("删除文件 (批量)")
    @Operation(summary = "删除文件 (批量)")
    @DeleteMapping("/api/upload/removeUploadFileBatch")
    public Result removeUploadFileBatch(@Validated(SysFile.DeleteBatch.class) @RequestBody SysFile sysFile) {

        // 判断是否存在
        List<String> object_keys = sysFile.getObject_keys();
        List<SysFile> querySysFileList = sysFileService.list(new LambdaQueryWrapper<SysFile>().in(SysFile::getObject_key, object_keys));
        if (querySysFileList != null && querySysFileList.size() != object_keys.size()) {
            throw new CustException("object_key 一个或多个不存在 (提交:" + object_keys.size() + ", 存在:" + querySysFileList.size() + ")");
        }

        // 权限：
        // - 删除自己 (需权限) (1.1.6)
        // - 删除其他人 (需要子权限或超级管理员) (1.1.5)
        Long my_user_id = SecurityUtil.getUserId();
        List<Long> sysFileListByUserId = querySysFileList.stream().map(SysFile::getUser_id).collect(Collectors.toList());
        if (sysFileListByUserId.contains(my_user_id) && !securityUtil.hasPermissions(Arrays.asList("1.1.5", "1.1.6"), MatchType.OR)) {
            throw new CustException(SecurityEnum.NOAUTH);
        }
        if (!sysFileListByUserId.contains(my_user_id) && !securityUtil.hasPermission("1.1.5")) {
            throw new CustException(SecurityEnum.NOAUTH);
        }

        return Result.success().put("data", sysFileService.removeUploadFileBatch(sysFile, querySysFileList));
    }




    @Operation(summary = "根据 MD5 获取文件列表 (我的)")
    @PreAuthorize("@sr.hasPermission('1.1.2')")
    @GetMapping("/api/upload/getUploadFileListByMd5")
    public Result getUploadFileListByMd5(@Validated(SysFile.SelectByMd5.class) SysFile sysFile) {
        sysFile.setUser_id(SecurityUtil.getUserId());
        return Result.success().put("data", sysFileService.getUploadFileListByMd5(sysFile));
    }

    @SysLog("合并重复 MD5 文件")
    @Operation(summary = "合并重复 MD5 文件")
    @PreAuthorize("@sr.hasPermission('1.1.4')")
    @PutMapping("/api/upload/mergeFileByMd5")
    public Result mergeFileByMd5(@Validated(SysFileMergeByMd5.MergeByMd5.class) @RequestBody SysFileMergeByMd5 sysFileMergeByMd5) {
        sysFileMergeByMd5.setUser_id(SecurityUtil.getUserId());
        return Result.success().put("data", sysFileService.mergeFileByMd5(sysFileMergeByMd5));
    }


}
