package cclotus.cloud.gateway.web

import com.cclotus.register.enum.UploadType
import com.ruoyi.common.config.RuoYiConfig
import com.ruoyi.common.core.domain.AjaxResult
import com.ruoyi.common.utils.DateUtils
import com.ruoyi.common.utils.StringUtils
import com.ruoyi.common.utils.file.FileUploadUtils
import com.ruoyi.common.utils.uuid.Seq
import org.apache.commons.io.FilenameUtils
import org.springframework.http.codec.multipart.FilePart
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestPart
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.io.File
import java.util.stream.Collectors


@RestController
@RequestMapping("/file")
class FileController {

    /**
     * 文件上传接口
     *
     * @param file 文件内容
     * @param type 文件类型
     * @return 上传结果
     */
    @PostMapping("/upload")
    fun upload(@RequestPart("file") file: FilePart, type: String?): AjaxResult {
        val baseDir = when (type) {
            UploadType.AVATAR.type -> {
                RuoYiConfig.getAvatarPath()
            }

            UploadType.IMPORT.type -> {
                RuoYiConfig.getImportPath()
            }

            UploadType.REPORT.type -> {
                RuoYiConfig.getProfile() + "/report"
            }

            else -> {
                RuoYiConfig.getUploadPath()
            }
        }
        val fileName = file.filename()
        val fileTempName = StringUtils.format(
            "{}/{}_{}.{}",
            DateUtils.datePath(),
            FilenameUtils.getBaseName(fileName),
            Seq.getId(Seq.uploadSeqType),
            FilenameUtils.getExtension(fileName)
        )
        val absPath = FileUploadUtils.getAbsoluteFile(baseDir, fileTempName).absolutePath
        file.transferTo(File(absPath)).subscribe()
        val ajax = AjaxResult.success()
        ajax["url"] = FileUploadUtils.getPathFileName(baseDir, fileTempName)
        ajax["fileName"] = fileName
        return ajax
    }

    /**
     * 文件批量上传
     * @param fileParts 文件列表
     * @param type 文件类型
     */
    @PostMapping("/multi/upload")
    fun upload(@RequestPart("files") fileParts: Flux<FilePart>, type: String?): Mono<AjaxResult> {
        val baseDir = when (type) {
            UploadType.AVATAR.type -> {
                RuoYiConfig.getAvatarPath()
            }

            UploadType.IMPORT.type -> {
                RuoYiConfig.getImportPath()
            }

            UploadType.REPORT.type -> {
                RuoYiConfig.getProfile() + "/report"
            }

            else -> {
                RuoYiConfig.getUploadPath()
            }
        }
        return fileParts.flatMap { file: FilePart ->
            val fileName = file.filename()
            val fileTempName = StringUtils.format(
                "{}/{}_{}.{}",
                DateUtils.datePath(),
                FilenameUtils.getBaseName(fileName),
                Seq.getId(Seq.uploadSeqType),
                FilenameUtils.getExtension(fileName)
            )
            val absPath = FileUploadUtils.getAbsoluteFile(baseDir, fileTempName).absolutePath
            file.transferTo(File(absPath)).subscribe()
            Mono.just(
                mapOf<String, String>(
                    "url" to FileUploadUtils.getPathFileName(baseDir, fileTempName),
                    "fileName" to fileName
                )
            )
        }.collect(Collectors.toList()).flatMap { items ->
            Mono.just(AjaxResult.success(items))
        }
    }
}
