package com.fs.app.controller;

import com.fs.common.config.FSConfig;
import com.fs.common.core.domain.R;
import com.fs.common.utils.security.OssUploadSecurityUtils;
import com.fs.core.utils.OrderCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 公共接口（部署于 Win 校验机时可接收校验文件落盘）
 */
@Api("公共接口")
@RestController
@RequestMapping(value = "/app/common")
@Slf4j
public class CommonController {

    @GetMapping("/genOrderCode")
    public R genOrderCode() {
        String orderCode = OrderCodeUtils.genOrderSn();
        if (StringUtils.isNotEmpty(orderCode)) {
            return R.ok().put("orderCode", orderCode);
        } else {
            return R.error("订单号生成失败");
        }
    }

    /**
     * 上传小程序域名校验文件：按原文件名保存到 fs.miniappVerifyPath，不做重命名。
     * 无鉴权，供销售公司后端内网调用。
     */
    @ApiOperation("上传小程序域名校验文件（原名落盘）")
    @PostMapping("/uploadMiniappVerifyFile")
    public R uploadMiniappVerifyFile(@RequestParam("file") MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return R.error("上传文件不能为空");
        }
        String verifyPath = FSConfig.getMiniappVerifyPath();
        if (StringUtils.isBlank(verifyPath)) {
            return R.error("未配置校验文件落盘路径 fs.miniappVerifyPath");
        }

        String originalName = file.getOriginalFilename();
        if (StringUtils.isBlank(originalName)) {
            return R.error("文件名不能为空");
        }
        String safeName;
        try {
            // 清洗为安全 basename，保留真实文件名（小程序校验要求精确原名落盘，同名覆盖）
            safeName = OssUploadSecurityUtils.sanitizeSafeFilename(originalName);
        } catch (Exception e) {
            return R.error(e.getMessage() == null ? "非法文件名" : e.getMessage());
        }

        try {
            Path baseDir = Paths.get(verifyPath).toAbsolutePath().normalize();
            if (!Files.exists(baseDir)) {
                Files.createDirectories(baseDir);
            }
            Path target = baseDir.resolve(safeName).normalize();
            if (!target.startsWith(baseDir)) {
                return R.error("非法文件路径");
            }
            File dest = target.toFile();
            file.transferTo(dest);
            log.info("小程序校验文件已落盘: path={}, size={}", target, file.getSize());
            return R.ok().put("fileName", safeName).put("path", target.toString());
        } catch (Exception e) {
            log.error("小程序校验文件落盘失败, fileName={}", safeName, e);
            return R.error("文件保存失败: " + e.getMessage());
        }
    }
}
