package com.ktg.web.controller.common;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.ktg.common.config.RuoYiConfig;
import com.ktg.common.constant.Constants;
import com.ktg.common.core.domain.AjaxResult;
import com.ktg.common.utils.FileDriveLetterUtils;
import com.ktg.common.utils.StringUtils;
import com.ktg.common.utils.file.FileUploadUtils;
import com.ktg.common.utils.file.FileUtils;
import com.ktg.framework.config.ServerConfig;
import com.ktg.iscs.domain.IsSystemAttribute;
import com.ktg.iscs.service.IIsSystemAttributeService;
import com.ktg.system.domain.SysUploadFile;
import com.ktg.system.service.ISysUploadFileService;
import io.jsonwebtoken.lang.Assert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用请求处理
 *
 * @author ruoyi
 */
@Api(tags = "通用请求处理-文件")
@RestController
@RequestMapping("/common")
public class CommonController {
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private ISysUploadFileService iSysUploadFileService;
    @Value("${ktg-mes.prod}")
    private String prodApi;
    @Autowired
    private IIsSystemAttributeService isSystemAttributeService;

    private static final String FILE_DELIMETER = ",";

    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete   是否删除
     */
    @ApiOperation("通用下载请求")
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {
        try {
            if (!FileUtils.checkAllowDownload(fileName)) {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete) {
                FileUtils.deleteFile(filePath);
            }
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求（单个）
     */
    @ApiOperation("通用上传请求（单个）")
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception {
        try {
            String url = null;
            String fileName = null;
            String newFileName = null;
            String originalFilename = file.getOriginalFilename();
            String absolutePath = null;
            IsSystemAttribute isSystemAttributeByKey = isSystemAttributeService.getIsSystemAttributeByKey("sys.upload.type");
            if (isSystemAttributeByKey == null || isSystemAttributeByKey.getSysAttrValue().equals("0")) {
                // 上传文件路径
                String filePath = RuoYiConfig.getUploadPath();
                // 上传并返回新文件名称
                fileName = FileUploadUtils.upload(filePath, file);
                if (StringUtils.isNotBlank(prodApi)) {
                    url = serverConfig.getUrl() + prodApi + fileName;
                    absolutePath = fileName.replace("/profile/upload", filePath);
                    newFileName = FileUtils.getName(fileName);
                } else {
                    url = serverConfig.getUrl() + fileName;
                    absolutePath = FileDriveLetterUtils.getDriveLetter() + fileName.replace("/profile/upload", filePath);
                    newFileName = FileUtils.getName(fileName);
                }
            } else if (isSystemAttributeByKey.getSysAttrValue().equals("1")) {
                Map<String, String> map = uploadByOss(file);
                url = map.get("url");
                absolutePath = map.get("newFileName");
                fileName = map.get("fileName");
                newFileName = map.get("newFileName");
                originalFilename = map.get("originalFilename");
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", newFileName);
            ajax.put("originalFilename", file.getOriginalFilename());

            // 2.开始新增文件上传信息
            SysUploadFile sysFile = new SysUploadFile();
            sysFile.setName(originalFilename);
            sysFile.setPath(absolutePath);
            sysFile.setUrl(url);
            sysFile.setType(file.getContentType());
            sysFile.setSize(file.getSize());
            iSysUploadFileService.insertSysUploadFile(sysFile);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /*public static void main(String[] args) {
        String path = System.getProperty("user.dir");
        System.out.println("path: " + path);
        String driveLetter = path.substring(0, 2);
        System.out.println("Drive letter: " + driveLetter);
        String os = System.getProperty("os.name").toLowerCase();
        System.out.println("os: " + os);
    }

    /**
     * 通用上传请求（多个）
     */
    @ApiOperation("通用上传请求（多个）")
    @PostMapping("/uploads")
    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception {
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            List<String> urls = new ArrayList<String>();
            List<String> fileNames = new ArrayList<String>();
            List<String> newFileNames = new ArrayList<String>();
            List<String> originalFilenames = new ArrayList<String>();
            for (MultipartFile file : files) {
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = serverConfig.getUrl() + fileName;
                urls.add(url);
                fileNames.add(fileName);
                newFileNames.add(FileUtils.getName(fileName));
                originalFilenames.add(file.getOriginalFilename());
                // 2.开始新增文件上传信息
                SysUploadFile sysFile = new SysUploadFile();
                sysFile.setName(fileName);
                sysFile.setPath(filePath);
                sysFile.setUrl(url);
                sysFile.setType(file.getContentType());
                sysFile.setSize(file.getSize());
                iSysUploadFileService.insertSysUploadFile(sysFile);
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载
     */
    @ApiOperation("本地资源通用下载")
    @GetMapping("/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        try {
            if (!FileUtils.checkAllowDownload(resource)) {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = RuoYiConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    @ApiOperation("monio上传")
    @PostMapping("/uploadMinio")
    public AjaxResult uploadFileMinio(MultipartFile file) throws Exception {
        try {
            String fileName = FileUploadUtils.uploadMinio(file);
            AjaxResult rt = AjaxResult.success();
            rt.put("url", fileName);
            rt.put("fileName", fileName);
            rt.put("newFileName", FileUtils.getName(fileName));
            rt.put("originalFileName", file.getOriginalFilename());
            return rt;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    // 配置参数（实际项目中建议从配置文件读取）
    private static final String ENDPOINT = "https://oss-cn-hangzhou.aliyuncs.com";
    private static final String ACCESS_KEY = "LTAI5t9wtz1o6ZJE5pwa2QGk";
    private static final String SECRET_KEY = "JUXGuxCb8in7mYfYrHtsqZfwhnvvPv";
    private static final String BUCKET_NAME = "iscs-dev";

    @ApiOperation("oss文件上传")
    @PostMapping("/upload-oss")
    public AjaxResult uploadFileByOss(@RequestParam("file") MultipartFile file) {
        Map<String, String> map = uploadByOss(file);
        return AjaxResult.success(map);
    }

    public Map<String, String> uploadByOss(MultipartFile file) {
        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        // String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String uniqueFileName = RuoYiConfig.getUploadPath().replaceFirst("/", "") + "/" + FileUploadUtils.extractFilename(file);

        // 初始化OSS客户端
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, SECRET_KEY);
        try {
            // 创建上传请求
            PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, uniqueFileName, file.getInputStream());

            // 上传文件（默认私有权限，如需公共读可设置ACL）
            ossClient.putObject(request);

            // 返回文件访问URL（需要拼接Bucket域名）
            String fileUrl = "https://" + BUCKET_NAME + "." + ENDPOINT.replace("https://", "") + "/" + uniqueFileName;
            HashMap<String, String> map = new HashMap<>();
            map.put("url", fileUrl);
            map.put("fileName", originalFilename);
            map.put("newFileName", uniqueFileName);
            map.put("originalFilename", originalFilename);
            return map;
        } catch (IOException e) {
            Assert.isTrue(false, "上传失败：" + e.getMessage());
        } catch (Exception e) {
            Assert.isTrue(false, "OSS异常：" + e.getMessage());
        } finally {
            // 关闭客户端
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    /**
     * 删除OSS文件接口
     *
     * @param fileName 要删除的文件名（包含路径）
     * @return 操作结果
     */
    @ApiOperation("删除OSS文件接口")
    @DeleteMapping("/delete-oss")
    public AjaxResult deleteFile(@RequestParam String fileName) {
        // 初始化OSS客户端
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, SECRET_KEY);

        try {
            // 删除文件
            ossClient.deleteObject(BUCKET_NAME, fileName);
            return AjaxResult.success("删除成功：" + fileName);
        } catch (OSSException e) {
            // OSS相关异常（如文件不存在、权限不足等）
            return AjaxResult.error("删除失败：" + e.getErrorMessage());
        } catch (Exception e) {
            // 其他异常（如网络问题）
            return AjaxResult.error("删除异常：" + e.getMessage());
        } finally {
            // 关闭客户端连接
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

}
