package com.webchat.controller;

import com.webchat.common.bean.APIResponseBean;
import com.webchat.common.bean.APIResponseBeanUtil;
import com.webchat.common.enums.FileTypeEnum;
import com.webchat.common.exception.BusinessException;
import com.webchat.config.annotation.ValidateLogin;
import com.webchat.domain.vo.response.EditorUpdateResultResponse;
import com.webchat.domain.vo.response.EditorUpdateResultResponseVO;
import com.webchat.domain.vo.response.UploadResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
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.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/api/file")
public class FileUploadController {

    /**
     * 定义文件存储路径
     */
    private static final String UPLOAD_IMAGE_DIR = "static/upload/image/";
    private static final String UPLOAD_VIDEO_DIR = "static/upload/video/";
    private static final String UPLOAD_FILE_DIR = "static/upload/file/";

    /**
     * 定义图片和视频的MIME类型列表
     */
    private static final List<String> IMAGE_MIME_TYPES = Arrays.asList("image/jpeg", "image/png", "image/gif", "image/bmp");
    private static final List<String> VIDEO_MIME_TYPES = Arrays.asList("video/mp4", "video/quicktime", "video/x-msvideo", "video/3gpp", "video/3gpp2", "video/webm", "video/ogg");


    /**
     * 文件上传接口
     * 上传文件到项目下
     * @param file
     * @return
     */
    @ValidateLogin
    @PostMapping("/moment/upload")
    public APIResponseBean<UploadResultVO> handleFileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException("上传文件为空！");
        }
        try {
            String fileType = "";
            // 获取文件的MIME类型
            String mimeType = file.getContentType();
            // 发布动态上传文件仅支持图片和视频
            String uploadDirPath = UPLOAD_IMAGE_DIR;
            if (IMAGE_MIME_TYPES.contains(mimeType)) {
                // 上传图片
                uploadDirPath = UPLOAD_IMAGE_DIR;
                fileType = FileTypeEnum.IMAGE.name();
            } else if (VIDEO_MIME_TYPES.contains(mimeType)) {
                uploadDirPath = UPLOAD_VIDEO_DIR;
                fileType = FileTypeEnum.VIDEO.name();
            } else {
                uploadDirPath = UPLOAD_FILE_DIR;
                fileType = FileTypeEnum.OTHER.name();
            }
            // 获取文件名
            String fileName = file.getOriginalFilename();
            String renameFileName = UUID.randomUUID().toString().replaceAll("-", "");
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            renameFileName = renameFileName + suffix;
            // 创建文件存储目录
            File uploadDir = new File(uploadDirPath);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            // 创建文件路径
            Path path = Paths.get(uploadDirPath + renameFileName);
            // 保存文件
            Files.copy(file.getInputStream(), path);
            // 返回文件存储路径的链接
            String absolutePath = path.toUri().toString();
            String relativePath = absolutePath.substring(absolutePath.lastIndexOf("/upload"));
            return APIResponseBeanUtil.success(UploadResultVO.of(relativePath, fileType, fileName));
        } catch (IOException e) {
            log.error("文件上传失败 =====> 失败原因:", e);
            throw new BusinessException("文件上传失败！");
        }
    }

    /**
     * 文件上传接口
     * 上传文件到项目下
     * @param file
     * @return
     */
    @ValidateLogin
    @PostMapping("/chat/upload")
    public APIResponseBean<UploadResultVO> chatUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException("上传文件为空！");
        }
        try {
            String fileType = "";
            // 获取文件的MIME类型
            String mimeType = file.getContentType();
            // 发布动态上传文件仅支持图片和视频
            String uploadDirPath = UPLOAD_IMAGE_DIR;
            if (IMAGE_MIME_TYPES.contains(mimeType)) {
                // 上传图片
                uploadDirPath = UPLOAD_IMAGE_DIR;
                fileType = FileTypeEnum.IMAGE.name();
            } else if (VIDEO_MIME_TYPES.contains(mimeType)) {
                uploadDirPath = UPLOAD_VIDEO_DIR;
                fileType = FileTypeEnum.VIDEO.name();
            } else {
                new BusinessException("仅支持图片和视频上传");
            }
            // 获取文件名
            String fileName = file.getOriginalFilename();
            String renameFileName = UUID.randomUUID().toString().replaceAll("-", "");
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            renameFileName = renameFileName + suffix;
            // 创建文件存储目录
            File uploadDir = new File(uploadDirPath);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            // 创建文件路径
            Path path = Paths.get(uploadDirPath + renameFileName);
            // 保存文件
            Files.copy(file.getInputStream(), path);
            // 返回文件存储路径的链接
            String absolutePath = path.toUri().toString();
            String relativePath = absolutePath.substring(absolutePath.lastIndexOf("/upload"));
            return APIResponseBeanUtil.success(UploadResultVO.of(relativePath, fileType, fileName));
        } catch (IOException e) {
            log.error("文件上传失败 =====> 失败原因:", e);
            throw new BusinessException("文件上传失败！");
        }
    }


    /**
     * 上传文件到本地，
     * 支持编辑器上传场景
     *
     * @param file
     * @return
     */
    @PostMapping("/updateForEditor")
    public EditorUpdateResultResponse updateForEditor(@RequestParam("file") MultipartFile file) {
        Assert.notNull(file != null, "未获取到文件！");

        Integer errno = 0;
        EditorUpdateResultResponseVO data = new EditorUpdateResultResponseVO();

        APIResponseBean<UploadResultVO> responseBean = this.handleFileUpload(file);
        if (APIResponseBeanUtil.isOk(responseBean)) {
            // 上传成功
            UploadResultVO uploadResult = responseBean.getData();
            data.setUrl(uploadResult.getUrl());
        } else {
            // 文件上传失败
            errno = -1;
        }
        return EditorUpdateResultResponse.of(errno, data);
    }
}