package com.ruoyi.web.controller.back;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.MusicInfo;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MusicUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.config.AliConfig;
import com.ruoyi.system.mapper.MusicInfoMapper;
import com.ruoyi.system.mapper.ShopUserMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.IShareInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RequestMapping("/file")
@RestController
public class FileController extends BaseController {

    @Autowired
    private ShopUserMapper shopUserMapper;
    @Autowired
    private SysUserPostMapper sysUserPostMapper;
    @Autowired
    private MusicInfoMapper musicInfoMapper;

    /**
     * 下载OSS文件
     */
    @GetMapping("/download/{objectName}/{fileName}")
    public void downloadOssFile(@RequestParam(value = "musicId",required = false) String musicId, @PathVariable("objectName") String objectName, @PathVariable("fileName") String fileName, HttpServletRequest request, HttpServletResponse response) {
        try {
            String ossPath = objectName + "/" + fileName;
            // 检查用户登录状态

            // 获取文件字节
           if (objectName.equals("musicFile")) {
               LoginUser userInfo = SecurityUtils.getLoginUser();
               if (userInfo == null){
                   response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                   response.setContentType("application/json;charset=UTF-8");
                   response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
                   return;
               }
               SysUser sysUser = userInfo.getUser();
              if (sysUser == null) {
//                  if (StrUtil.isBlank(musicId)) {
//                      response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
//                      response.setContentType("application/json;charset=UTF-8");
//                      response.getWriter().write("{\"code\":400,\"msg\":\"音乐ID不能为空\"}");
//                      return;
//                  }
                  ShopUser shopUser = userInfo.getShopUser();
                  if (shopUser == null) {
                      response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                      response.setContentType("application/json;charset=UTF-8");
                      response.getWriter().write("{\"code\":401,\"msg\":\"用户未登录\"}");
                      return;
                  }
                  //shopUser = shopUserMapper.selectShopUserByUserId(userId);
//                  MusicInfo musicInfo = musicInfoMapper.selectByMusicId(musicId);
//
//                  if (musicInfo == null) {
//                      response.setStatus(HttpServletResponse.SC_NOT_FOUND);
//                      response.setContentType("application/json;charset=UTF-8");
//                      response.getWriter().write("{\"code\":404,\"msg\":\"音乐信息不存在\"}");
//                      return;
//                  }

//                  if (musicInfo.getVip() != null && musicInfo.getVip() == 1) {
//                      // 判断用户vip
//                      if (!MusicUtil.getShopIsVip(shopUser)) {
//                          response.setStatus(HttpServletResponse.SC_FORBIDDEN);
//                          response.setContentType("application/json;charset=UTF-8");
//                          response.getWriter().write("{\"code\":403,\"msg\":\"该音乐为VIP专享，请升级VIP后下载\"}");
//                          return;
//                      }
//                  }
              }
           }

            // 设置响应头
            String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
            if (fileExtension.equals("mp3")) {
                // 获取文件总长度，这对iOS客户端获取时长非常重要
                Long contentLength = getOssObjectLength(ossPath);

                // 对于MP3文件，设置为音频流，支持直接播放
                response.setContentType("audio/mpeg");

                // 设置Content-Length头，这对iOS客户端获取时长至关重要
                if (contentLength != null) {
                    response.setHeader("Content-Length", contentLength.toString());
                }

                // 允许范围请求，支持断点续传和iOS客户端获取时长
                response.setHeader("Accept-Ranges", "bytes");

                // 添加iOS兼容性头信息
                response.setHeader("Cache-Control", "public, max-age=3600");

                // 处理Range请求（支持拖动播放和iOS客户端获取时长）
                String rangeHeader = request.getHeader("Range");
                if (rangeHeader != null && rangeHeader.startsWith("bytes=") && contentLength != null) {
                    handleRangeRequest(rangeHeader, contentLength, ossPath, response);
                    return;
                }

                // 不设置Content-Disposition，这样浏览器会直接播放而不是下载
            } else {
                // 其他文件类型，保持下载行为
                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            }

            // 设置缓冲区大小和连接保持
            response.setBufferSize(8192); // 8KB缓冲区
            response.setHeader("Connection", "Keep-Alive");

            try {
                // 使用流式下载而不是一次性加载全部内容到内存
                boolean success = AliConfig.ossDownloadStream(ossPath, response.getOutputStream());
                if (!success) {
                    if (!response.isCommitted()) {
                        response.reset();
                        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在或下载失败\"}");
                    }
                    return;
                }
            } catch (IOException e) {
                // 检查是否为客户端断开连接的错误（Broken pipe）
                if (e.getMessage() != null &&
                    (e.getMessage().contains("Broken pipe") ||
                     e.getMessage().contains("Connection reset by peer") ||
                     e.getMessage().contains("连接被对方重置") ||
                     e.getMessage().contains("你的主机中的软件中止了一个已建立的连接") ||
                     e.getMessage().contains("Software caused connection abort"))) {
                    // 客户端已断开连接，记录日志但不作为错误处理
                    logger.info("客户端断开连接，文件传输中断: {}", e.getMessage());
                } else {
                    // 其他IO错误，重新抛出
                    throw e;
                }
            }
        } catch (Exception e) {
            try {
                // 检查是否为客户端断开连接的错误
                if (e instanceof IOException && e.getMessage() != null &&
                    (e.getMessage().contains("Broken pipe") ||
                     e.getMessage().contains("Connection reset by peer") ||
                     e.getMessage().contains("连接被对方重置") ||
                     e.getMessage().contains("你的主机中的软件中止了一个已建立的连接") ||
                     e.getMessage().contains("Software caused connection abort"))) {
                    // 客户端已断开连接，记录日志但不作为错误处理
                    logger.info("客户端断开连接，文件传输中断: {}", e.getMessage());
                } else {
                    // 其他错误，返回错误响应
                    e.printStackTrace();
                    // 检查响应是否已提交
                    if (!response.isCommitted()) {
                        response.reset();
                        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getWriter().write("{\"code\":500,\"msg\":\"下载失败: " + e.getMessage() + "\"}");
                    }
                }
            } catch (Exception ignored) {
                // 处理异常时出现的异常，忽略
            }
        }
    }

    /**
     * 获取OSS对象长度
     */
    private Long getOssObjectLength(String ossPath) {
        try {
            return AliConfig.getOssObjectLength(ossPath);
        } catch (Exception e) {
            logger.warn("无法获取文件长度: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 处理Range请求
     */
    private void handleRangeRequest(String rangeHeader, Long contentLength, String ossPath, HttpServletResponse response) throws IOException {
        // 解析Range头
        String[] ranges = rangeHeader.substring(6).split("-");
        long start = Long.parseLong(ranges[0]);
        long end = (ranges.length > 1 && !ranges[1].isEmpty())
            ? Long.parseLong(ranges[1])
            : contentLength - 1;

        // 确保范围有效
        if (start >= contentLength) {
            response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            response.setHeader("Content-Range", "bytes */" + contentLength);
            return;
        }

        if (end >= contentLength) {
            end = contentLength - 1;
        }

        // 设置部分内容响应
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + contentLength);
        response.setHeader("Content-Length", String.valueOf(end - start + 1));

        // 使用范围下载
        try {
            boolean success = ossDownloadStreamRange(ossPath, response.getOutputStream(), start, end);
            if (!success) {
                handleFileNotFound(response);
            }
        } catch (IOException e) {
            handleIOException(e);
        }
    }

    /**
     * OSS范围下载
     */
    private boolean ossDownloadStreamRange(String ossPath, java.io.OutputStream outputStream, long start, long end) {
        try {
            return AliConfig.ossDownloadStreamRange(ossPath, outputStream, start, end);
        } catch (Exception e) {
            logger.error("范围下载失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 处理文件未找到
     */
    private void handleFileNotFound(HttpServletResponse response) throws IOException {
        if (!response.isCommitted()) {
            response.reset();
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在或下载失败\"}");
        }
    }

    /**
     * 处理IO异常
     */
    private void handleIOException(IOException e) throws IOException {
        if (e.getMessage() != null &&
            (e.getMessage().contains("Broken pipe") ||
             e.getMessage().contains("Connection reset by peer") ||
             e.getMessage().contains("连接被对方重置") ||
             e.getMessage().contains("你的主机中的软件中止了一个已建立的连接") ||
             e.getMessage().contains("Software caused connection abort"))) {
            logger.info("客户端断开连接，文件传输中断: {}", e.getMessage());
        } else {
            throw e;
        }
    }

}
