package com.fs.app.controller;


import com.fs.app.annotation.Login;
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.exception.file.OssException;
import com.fs.common.utils.ServletUtils;
import com.fs.course.domain.FsUserTalent;
import com.fs.course.domain.FsUserTalentFollow;
import com.fs.course.domain.FsUserVideo;
import com.fs.course.param.FsUserTalentFansParam;
import com.fs.course.param.FsUserTalentFollowParam;
import com.fs.course.param.FsUserVideoAddParam;
import com.fs.course.param.FsUserVideoListUParam;
import com.fs.course.service.IFsUserTalentFollowService;
import com.fs.course.service.IFsUserTalentService;
import com.fs.course.service.IFsUserVideoService;
import com.fs.course.service.IFsUserVideoTagsService;
import com.fs.course.vo.FsUserVideoListUVO;
import com.fs.course.vo.FsUserVideoTagsPVO;
import com.fs.his.domain.FsUser;
import com.fs.his.service.IFsUserService;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.fs.utils.VideoUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Synchronized;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Api("达人接口")
@RestController
@RequestMapping(value="/app/talent")
public class TalentController extends  AppBaseController{
    @Autowired
    private IFsUserTalentFollowService userTalentFollowService;
    @Autowired
    private IFsUserTalentService userTalentService;
    @Autowired
    private IFsUserService fsUserService;
    @Autowired
    private IFsUserVideoService fsUserVideoService;
    @Autowired
    private IFsUserVideoTagsService fsUserVideoTagsService;

    private static final String VIDEO_UPLOAD_DIR = "C:\\fs\\uploadPath\\talent\\video";  // 上传目录
    private static final String FRAME_OUTPUT_DIR = "C:\\fs\\uploadPath\\talent\\frame";  // 输出帧的目录


    @ApiOperation("获取指定达人详情")
    @GetMapping("/getTalentByUserId")
    @Login
    private R getTalentById(@RequestParam("userId")Long userId){
        return userTalentService.getTalentDetail(userId,Long.parseLong(getUserId()));
    }
    @Login
    @ApiOperation("获当前登录用户达人详情")
    @GetMapping("/getTalentByToken")
    private R getTalentByToken(){
        //点击进入达人页面入口时，有可能当前用户还不是达人，需要自动注册成为达人
        //查询基本信息
        String userId = getUserId();
        FsUserTalent fsUserTalent = userTalentService.queryTalentByUserId(Long.parseLong(userId));
        if (null==fsUserTalent){
            FsUser fsUser = fsUserService.selectFsUserByUserId(Long.parseLong(userId));
            //新增达人
            userTalentService.addFsUserTalent(fsUser.getUserId());
        }
        return userTalentService.getTalentDetail(Long.parseLong(userId),0l);
    }

    @ApiOperation("获取达人粉丝列表")
    @GetMapping("/getTalentFansByUserId")
    private TableDataInfo getFansByUserId(FsUserTalentFansParam param){
        startPage();
        param.setUserId(null);
        return getDataTable(userTalentFollowService.selectFsUserTalentFansVoList(param));
    }

    @Login
    @ApiOperation("获取达人关注列表")
    @GetMapping("/getTalentFollowByUserId")
    private TableDataInfo getFollowByUserId(FsUserTalentFansParam param){
        startPage();
        param.setTalentId(null);
        param.setUserId(Long.parseLong(getUserId()));
        return getDataTable(userTalentFollowService.selectFsUserFollowVoList(param));
    }


    @Login
    @ApiOperation("获取是否关注")
    @GetMapping("/checkFollow")
    public R checkFollow(@RequestParam("talentId")Long talentId, HttpServletRequest request){
        String headValue =  ServletUtils.getRequest().getHeader("APPToken");
        Claims claims=jwtUtils.getClaimByToken(headValue);
        if(claims!=null){
            String userId = claims.getSubject().toString();
            R r=userTalentFollowService.checkFollow(talentId,Long.parseLong(userId));
            if (r.get("code").equals(200)){
                return R.ok().put("isFollow",1);
            }else {
                return R.ok().put("isFollow",0);
            }
//            return courseFollowService.checkFollow(courseId,Long.parseLong(userId));
        }
        else{
            return R.error("未登录");
        }

    }
    @Login
    @ApiOperation("关注")
    @PostMapping("/doFollow")
    //@Transactional
    @Synchronized
    public R doFollow(@RequestBody FsUserTalentFollowParam param, HttpServletRequest request){
        R r=userTalentFollowService.checkFollow(param.getTalentId(),Long.parseLong(getUserId()));
        if(r.get("code").equals(200)){
            //取消关注
            userTalentFollowService.deleteFollow(param.getTalentId(),Long.parseLong(getUserId()));
            userTalentService.updateFans(param.getTalentId(),1);
            return R.ok("已取消关注");
        }
        else{
            //关注
            FsUserTalentFollow map=new FsUserTalentFollow();
            map.setTalentId(param.getTalentId());
            map.setUserId(Long.parseLong(getUserId()));
            map.setCreateTime(new Date());
            userTalentFollowService.insertFsUserTalentFollow(map);
            userTalentService.updateFans(param.getTalentId(),-1);
            return R.ok("已关注");
        }

    }

    /**
     * 达人上传视频
     * @param file
     * @return
     * @throws Exception
     */
    @Login
    @PostMapping("/uploadOSSTalent")
    public R uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        //校验文件是否为空
        if (file.isEmpty()) {
            throw new OssException("上传文件不能为空");
        }

        // 后缀白名单 + 路径穿越字符过滤
        String suffix = com.fs.common.utils.security.OssUploadSecurityUtils.validateAndGetDotSuffix(file);
        String originalFilename = file.getOriginalFilename();
        String fileType = file.getContentType();

        //如果是视频文件且需要缩略图
        if (fileType != null && fileType.startsWith("video/")) {
            // 3.1 校验视频格式（示例仅允许MP4）
            if (!".mp4".equalsIgnoreCase(suffix) && !fileType.equals("video/mp4")) {
                return R.error("仅支持MP4视频格式");
            }

            // UUID 重命名，禁止使用原始文件名拼接本地路径（防路径穿越）
            String videoFileName = UUID.randomUUID().toString().replace("-", "") + ".mp4";
            File uploadDir = new File(VIDEO_UPLOAD_DIR);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            File videoFile = new File(uploadDir, videoFileName);
            // 二次确认落盘路径仍在约定目录内
            if (!videoFile.getCanonicalPath().startsWith(uploadDir.getCanonicalPath())) {
                throw new OssException("文件路径非法");
            }
            file.transferTo(videoFile);

            //获取视频元信息（宽高、大小、时长等）
            Map<String, Object> videoInfo = VideoUtil.getVideoInfo(videoFile);

            //提取第一帧作为缩略图
            String frameFileName = FilenameUtils.removeExtension(videoFileName) + "_frame.jpg";
            File frameFile = new File(FRAME_OUTPUT_DIR, frameFileName);
            VideoUtil.extractFirstFrame(videoFile.getAbsolutePath(), frameFile.getAbsolutePath());

            //上传缩略图到OSS
            CloudStorageService storage = OSSFactory.build();
            UUID uuid = UUID.randomUUID();
            //上传原始视频到OSS
            byte[] fileBytes = Files.readAllBytes(videoFile.toPath()); // 从临时文件读取
            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String path = "fs/talent/" + dateStr + "/" + uuid + ".mp4";
            String videoUrl = storage.upload(fileBytes, path);
            //上传缩略图到OSS
            String thumbnailPath = "fs/talent/" + dateStr + "/" + uuid + ".jpg"; // 改为.jpg
            String thumbnailUrl;
            try (InputStream inputStream = new FileInputStream(frameFile)) {
                thumbnailUrl = storage.upload(inputStream, thumbnailPath); // 使用相同路径规则
            }
            //清理临时文件
            videoFile.delete();
            frameFile.delete();

            return R.ok()
                    .put("url", videoUrl)          // 视频URL
                    .put("thumbnailUrl", thumbnailUrl) // 缩略图URL
                    .put("videoInfo", videoInfo);     // 视频元信息
        }

        //普通文件上传（图片/文档等）
        CloudStorageService storage = OSSFactory.build();
        String fileUrl = storage.uploadSuffix(file.getBytes(), suffix);

        //返回普通文件URL
        return R.ok()
                .put("url", fileUrl)
                .put("fileType", fileType);
    }
    @Login
    @ApiOperation("达人提交上上传视频后返回的数据")
    @PostMapping("/talentVideo")
    private R talentVideo(@RequestBody FsUserVideoAddParam param){
        String userId = getUserId();
        FsUserTalent fsUserTalent = userTalentService.queryTalentByUserId(Long.parseLong(userId));
        if (null==fsUserTalent){
            return R.error("请先注册达人身份");
        }
        param.setTalentId(fsUserTalent.getTalentId());
        return fsUserVideoService.addUserVideoByTalent(param);
    }
    @Login
    @ApiOperation("视频列表")
    @GetMapping("/getVideoList")
    public R getVideoList(FsUserVideoListUParam param)
    {
        long userId = Long.parseLong(getUserId());
        if (null==param.getUserId()||param.getUserId()<=0){
            param.setUserId(userId);
        }
        FsUserTalent fsUserTalent = userTalentService.queryTalentByUserId(param.getUserId());
        if (null==fsUserTalent){
            return R.error("您选择的用户还未注册达人");
        }
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        boolean oneSelf = userId == param.getUserId();
        List<FsUserVideoListUVO> list = fsUserVideoService.selectFsUserVideoListUVOByUser(fsUserTalent.getTalentId(),oneSelf,userId);
        list = fsUserVideoService.addNum(list);

        PageInfo<FsUserVideoListUVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("修改达人信息")
    @PostMapping("/updateTalent")
    public R updateTalent(@RequestBody FsUserTalent fsUserTalent)
    {
        String userId = getUserId();
        fsUserTalent.setUserId(Long.parseLong(userId));
        fsUserTalent.setUpdateTime(new Date());
        userTalentService.updateFsUserTalentByUser(fsUserTalent);
        return R.ok();
    }


    @Login
    @ApiOperation("达人视频删除")
    @PostMapping("/deleteVideo")
    public R deleteVideo(@RequestBody FsUserVideo fsUserVideo)
    {
        Long userId = Long.parseLong(getUserId());
        return fsUserVideoService.deleteFsUserVideoByVideoIdWithVerify(fsUserVideo.getVideoId(), userId);
    }

    @Login
    @ApiOperation("更新达人视频状态")
    @PostMapping("/updateVideoStatus")
    public R updateVideoStatus(@RequestBody FsUserVideo fsUserVideo)
    {
        Long userId = Long.parseLong(getUserId());
        return fsUserVideoService.updateVideoStatusWithVerify(fsUserVideo, userId);
    }

    @GetMapping("/subList")
    public AjaxResult subList()
    {
        List<FsUserVideoTagsPVO> list = fsUserVideoTagsService.selectFsUserVideoTagsSubList();
        return AjaxResult.success(list);
    }
}
