package com.fs.course.controller;

import com.fs.common.annotation.Log;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.core.page.TableDataInfo;
import com.fs.common.enums.BusinessType;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.core.security.LoginUser;
import com.fs.core.security.SecurityUtils;
import com.fs.course.domain.FsUserVideo;
import com.fs.course.param.FsUserVideoAddParam;
import com.fs.course.param.FsUserVideoAuditParam;
import com.fs.course.param.FsUserVideoParam;
import com.fs.course.service.IFsUserVideoService;
import com.fs.course.vo.FsUserVideoListPVO;
import com.fs.course.vo.FsUserVideoPVO;
import com.fs.store.service.IFsStoreProductAttrValueService;
import com.fs.store.service.IFsStoreProductPackageService;
import com.fs.store.service.IFsStoreProductService;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 课堂视频Controller
 *
 * @author fs
 * @date 2024-05-15
 */
@RestController
@RequestMapping("/course/userVideo")
public class FsUserVideoController extends BaseController
{
    @Autowired
    private IFsUserVideoService fsUserVideoService;
    @Autowired
    private IFsStoreProductPackageService fsStoreProductPackageService;
    @Autowired
    private IFsStoreProductAttrValueService attrValueService;
    @Autowired
    private IFsStoreProductService storeProductService;

    /**
     * 查询课堂视频列表
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:list')")
    @GetMapping("/list")
    public TableDataInfo list(FsUserVideoParam fsUserVideo)
    {
        startPage();
        List<FsUserVideoListPVO> list = fsUserVideoService.selectFsUserVideoListPVO(fsUserVideo);
        return getDataTable(list);
    }

    /**
     * 导出课堂视频列表
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:export')")
    @Log(title = "课堂视频", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(FsUserVideo fsUserVideo)
    {
        List<FsUserVideo> list = fsUserVideoService.selectFsUserVideoList(fsUserVideo);
        ExcelUtil<FsUserVideo> util = new ExcelUtil<FsUserVideo>(FsUserVideo.class);
        return util.exportExcel(list, "课堂视频数据");
    }

    /**
     * 获取课堂视频详细信息
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:query')")
    @GetMapping(value = "/{videoId}")
    public AjaxResult getInfo(@PathVariable("videoId") String videoId)
    {
        return AjaxResult.success(fsUserVideoService.selectFsUserVideoByVideoId(videoId));
    }

    @GetMapping(value = "/getVideoDetails")
    public R getVideoDetails(@RequestParam("videoId") Long videoId)
    {
        FsUserVideoPVO videoPVO = fsUserVideoService.selectFsUserVideoPVOByVideoId(videoId);
//        FsStoreProductPackage productPackage =null;
//        if (videoPVO.getProductId()!=null ) {
//            productPackage=fsStoreProductPackageService.selectFsStoreProductPackageById(videoPVO.getProductId());
//            List<StoreOrderProductDTO> productList=new ArrayList<>();
//            JSONArray jsonArray= JSONUtil.parseArray(productPackage.getProducts());
//            List<StorePackageProductDTO> goodsList=JSONUtil.toList(jsonArray, StorePackageProductDTO.class);
//            for(StorePackageProductDTO dto:goodsList){
//                StoreOrderProductDTO productDTO=new StoreOrderProductDTO();
//                FsStoreProductAttrValue attrValue=attrValueService.selectFsStoreProductAttrValueById(dto.getId());
//                if(attrValue!=null){
//                    FsStoreProduct product=storeProductService.selectFsStoreProductById(attrValue.getProductId());
//                    if(product!=null){
//                        productDTO.setProductId(attrValue.getProductId());
//                        productDTO.setId(dto.getId());
//                        productDTO.setBarCode(attrValue.getBarCode());
//                        productDTO.setPrice(attrValue.getPrice());
//                        productDTO.setCount(dto.getCount());
//                        productDTO.setSku(attrValue.getSku());
//                        productDTO.setImage(attrValue.getImage());
//                        productDTO.setProductName(product.getProductName());
//                        productList.add(productDTO);
//                    }
//                }
//            }
//            productPackage.setProductList(productList);
//        }
       return R.ok().put("data", videoPVO);
    }

    /**
     * 新增课堂视频
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:add')")
    @Log(title = "课堂视频", businessType = BusinessType.INSERT)
    @PostMapping("/addVideo")
    public R add(@RequestBody FsUserVideoAddParam param)
    {
        return fsUserVideoService.addUserVideo(param);
    }

    /**
     * 修改课堂视频
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:edit')")
    @Log(title = "课堂视频", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FsUserVideo fsUserVideo)
    {
        return toAjax(fsUserVideoService.updateFsUserVideo(fsUserVideo));
    }

    /**
     * 删除课堂视频
     */
    @PreAuthorize("@ss.hasPermi('course:userVideo:remove')")
    @Log(title = "课堂视频", businessType = BusinessType.DELETE)
	@DeleteMapping("/{videoIds}")
    public AjaxResult remove(@PathVariable String[] videoIds)
    {
        return toAjax(fsUserVideoService.deleteFsUserVideoByVideoIds(videoIds));
    }

    @GetMapping("/getVideoListByCourseId")
    public TableDataInfo getVideoListByCourseId(FsUserVideo fsUserVideo)
    {
        startPage();
        List<FsUserVideo> list = fsUserVideoService.selectFsUserVideoListByCourseId(fsUserVideo);
        return getDataTable(list);
    }


    @PreAuthorize("@ss.hasPermi('course:userVideo:audit')")
    @Log(title = "审核视频", businessType = BusinessType.UPDATE)
    @PostMapping("/auditVideo")
    public R auditVideo(@RequestBody FsUserVideoAuditParam param)
    {
        param.setAuditTime(new Date());
        LoginUser user = SecurityUtils.getLoginUser();
        param.setAuditBy(user.getUser().getUserId());
        if (param.getIsAudit()==-1){
            param.setStatus(0);
        }
        if (fsUserVideoService.auditUserVideos(param)>0){
            return R.ok("审核成功");
        }
        return R.error("审核失败");
    }

    @PreAuthorize("@ss.hasPermi('course:userVideo:putOn')")
    @Log(title = "短视频批量上架", businessType = BusinessType.UPDATE)
    @PostMapping("/putOn/{videoIds}")
    public AjaxResult putOn(@PathVariable Long[] videoIds)
    {
        return toAjax(fsUserVideoService.updateFsUserVideoIsShow(videoIds,1));
    }

    @PreAuthorize("@ss.hasPermi('course:userVideo:putOn')")
    @Log(title = "短视频批量下架", businessType = BusinessType.UPDATE)
    @PostMapping("/pullOff/{videoIds}")
    public AjaxResult pullOff(@PathVariable Long[] videoIds)
    {
        return toAjax(fsUserVideoService.updateFsUserVideoIsShow(videoIds,0));
    }

    private static final String VIDEO_UPLOAD_DIR = "C:\\fs\\uploadPath\\userVideo\\video";  // 上传目录
    private static final String FRAME_OUTPUT_DIR = "C:\\fs\\uploadPath\\userVideo\\frame";  // 输出帧的目录
    /**
     * 获取视频第一帧为封面
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/getThumbnail")
    public R uploadVideo(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty() || !file.getContentType().equals("video/mp4")) {
            return R.error("仅支持MP4类型");
        }

        // 保存上传的视频文件
        String videoFileName = System.currentTimeMillis() + "_" + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
        File videoFile = new File(VIDEO_UPLOAD_DIR, videoFileName);
        try {
            file.transferTo(videoFile);
        } catch (IOException e) {
            // 记录错误日志
            return R.error("获取封面失败");
        }

        // 提取视频第一帧
        String frameFileName = FilenameUtils.removeExtension(videoFileName) + "_frame.jpg";
        File frameFile = new File(FRAME_OUTPUT_DIR, frameFileName);
        try {
            extractFirstFrame(videoFile.getAbsolutePath(), frameFile.getAbsolutePath());
        } catch (Exception e) {
            // 记录错误日志
            return R.error("提取第一帧失败");
        }

        // 上传第一帧图片到 COS
        String suffix = ".jpg";
        CloudStorageService storage = OSSFactory.build();
        String url;
        try (InputStream inputStream = new FileInputStream(frameFile)) {
            url = storage.uploadSuffix(inputStream, suffix);
        }  catch (Exception e) {
            // 记录错误日志
            return R.error("上传封面图失败");
        } finally {
            // 清理临时文件
            videoFile.delete();
            frameFile.delete();
        }

        // 返回第一帧图片的 COS URL
        return R.ok().put("url", url);
    }

    // 提取视频第一帧的方法
    private void extractFirstFrame(String videoPath, String outputImagePath) throws IOException, InterruptedException {
        String[] command = {
                "ffmpeg",
                "-i", videoPath,
//                "-ss", "00:00:01.000", // 截取1秒处的帧
                "-frames:v", "1",
                "-f", "image2",
                "-update", "1",
                "-q:v", "10", // 质量，1为最好，31为最差
                outputImagePath
        };
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true); // 将标准错误和标准输出合并
        Process process = processBuilder.start();
//        process.waitFor();

        // 处理进程的标准输出和错误流
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line); // 输出到控制台或日志
            }
        }

        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("FFmpeg 执行失败，退出代码：" + exitCode);
        }
    }

}
