package com.ycwl.basic.controller.extern;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ycwl.basic.annotation.IgnoreToken;
import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.MemberMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.mobile.face.FaceRecognizeResp;
import com.ycwl.basic.model.mobile.goods.GoodsDetailVO;
import com.ycwl.basic.model.mobile.goods.GoodsReqQuery;
import com.ycwl.basic.model.mobile.goods.VideoTaskStatusVO;
import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.member.entity.MemberEntity;
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.repository.VideoRepository;
import com.ycwl.basic.service.mobile.AppScenicService;
import com.ycwl.basic.service.mobile.GoodsService;
import com.ycwl.basic.service.pc.FaceService;
import com.ycwl.basic.service.task.impl.TaskTaskServiceImpl;
import com.ycwl.basic.utils.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
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 jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/ly")
public class LyCompatibleController {
    @Autowired
    private FaceService faceService;

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private FaceMapper faceMapper;
    @Autowired
    private VideoRepository videoRepository;
    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private TaskTaskServiceImpl taskTaskServiceImpl;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @PostMapping("sendPhoto")
    @IgnoreToken
    public R sendPhoto(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request) {
        Map<String, String> headersMap = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            headersMap.put(key, value);
        }
        if (!headersMap.containsKey("client")) {
            return R.error("请在Header中传入client！（client:用户OpenId）");
        }
        if (!headersMap.containsKey("secret")) {
            return R.error("请传入秘钥！");
        }
        String scid = request.getParameter("scid");
        long scenicId;
        if (StringUtils.isBlank(scid)) {
            return R.error("景区ID为空！");
        }
//        if (StringUtils.equals("288",scid)) {
            scenicId = 3955650120997015552L;
//        } else {
//            scenicId = 3946669713328836608L;
//        }
        String openId = headersMap.get("client");
        MemberRespVO member = memberMapper.getByOpenId(openId);
        if (member == null) {
            member = new MemberRespVO();
            MemberEntity memberEntity = new MemberEntity();
            memberEntity.setOpenId(openId);
            memberEntity.setScenicId(scenicId);
            memberEntity.setCreateDate(new Date());
            memberEntity.setId(SnowFlakeUtil.getLongId());
            memberEntity.setNickname("用户");
            memberMapper.add(memberEntity);
            member.setId(memberEntity.getId());
        } else {
            MemberEntity memberUpd = new MemberEntity();
            memberUpd.setId(member.getId());
            memberUpd.setScenicId(scenicId);
            memberUpd.setUpdateAt(new Date());
            memberMapper.update(memberUpd);
        }
        FaceRecognizeResp resp;
        try {
            resp = faceService.faceUpload(file, scenicId, member.getId());
        } catch (Exception e) {
            return R.error("上传失败！报错："+e.getMessage());
        }
        if (resp.getFaceId() == null) {
            return R.error("上传失败！");
        }
        return R.ok().put("data", resp);
    }

    @RequestMapping("getIsVideo")
    @IgnoreToken
    public R getIsVideo(HttpServletRequest request) {
        Map<String, String> headersMap = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            headersMap.put(key, value);
        }
        if (!headersMap.containsKey("client")) {
            return R.error("请在Header中传入client！（client:用户OpenId）");
        }
        if (!headersMap.containsKey("secret")) {
            return R.error("请传入秘钥！");
        }
        String openId = headersMap.get("client");
        MemberRespVO member = memberMapper.getByOpenId(openId);
        if (member == null) {
            return R.error("用户不存在！");
        }
        VideoTaskStatusVO taskStatusVO = goodsService.getTaskStatusByScenicId(member.getId(), member.getScenicId());
        if (taskStatusVO == null) {
            return R.ok().put("hasVideo", 0);
        }
        log.info("> {}", taskStatusVO);
        switch (taskStatusVO.getStatus()) {
            case 1:
                return R.ok().put("hasVideo", 1);
            case 2:
                if (taskStatusVO.getCutStatus() == 0) {
                    return R.ok().put("hasVideo", 3);
                } else {
                    return R.ok().put("hasVideo", 1);
                }
            case 0:
            case 3:
            default:
                return R.ok().put("hasVideo", 0);
        }
    }

    @RequestMapping("getNewVideo")
    @IgnoreToken
    public R getNewVideo(HttpServletRequest request) {
        Map<String, String> headersMap = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            headersMap.put(key, value);
        }
        if (!headersMap.containsKey("client")) {
            return R.error("请在Header中传入client！（client:用户OpenId）");
        }
        if (!headersMap.containsKey("secret")) {
            return R.error("请传入秘钥！");
        }
        String openId = headersMap.get("client");
        if (redisTemplate.hasKey("ly:"+openId)) {
            return JSON.parseObject(redisTemplate.opsForValue().get("ly:"+openId), R.class);
        }
        MemberRespVO member = memberMapper.getByOpenId(openId);
        if (member == null) {
            return R.error("用户不存在！");
        }
        FaceRespVO faceVO = faceMapper.getLatestByMemberId(member.getId(), member.getScenicId());
        if (faceVO == null) {
            return R.error("用户没有上传过照片！");
        }
        VideoTaskStatusVO taskStatusVO = goodsService.getTaskStatusByScenicId(member.getId(), member.getScenicId());
        List<ContentPageVO> listApiResponse = faceService.faceContentList(faceVO.getId());
        Map<Integer, List<ContentPageVO>> collect = listApiResponse.stream()
                .filter(contentPageVO -> contentPageVO.getLockType() < 0)
                .collect(Collectors.groupingBy(ContentPageVO::getGoodsType));
        R response = R.ok();
        if (collect.get(0) == null) {
            response.put("isgen", 1)
                    .put("newvideo", Collections.emptyList())
                    .put("newuservideo", Collections.emptyList());
            return response;
        }
        List<Map<String, Object>> videoList = collect.get(0).stream().collect(Collectors.groupingBy(ContentPageVO::getTemplateId))
                .values().stream().map(contentPageVOs -> {
                    ContentPageVO contentPageVO = contentPageVOs.getFirst();
                    Map<String, Object> map = new HashMap<>();
                    VideoEntity videoRespVO = videoRepository.getVideo(contentPageVO.getContentId());
                    map.put("id", videoRespVO.getId().toString());
                    map.put("template_cover_image", contentPageVO.getTemplateCoverUrl());
                    Date taskShotDate = taskTaskServiceImpl.getTaskShotDate(videoRespVO.getTaskId());
                    map.put("shoottime", DateUtil.format(taskShotDate, "yyyy-MM-dd HH:mm"));
                    map.put("openid", openId);
                    map.put("scenicname", contentPageVO.getScenicName());
                    map.put("title", contentPageVO.getName());
                    map.put("ossurldm", videoRespVO.getVideoUrl());
                    return map;
                }).collect(Collectors.toList());
        GoodsReqQuery goodsReqQuery = new GoodsReqQuery();
        goodsReqQuery.setFaceId(faceVO.getId());
        goodsReqQuery.setSourceType(1);
        List<GoodsDetailVO> sourceGoodsList = goodsService.sourceGoodsList(goodsReqQuery);
        List<Map<String, Object>> userVideoList = sourceGoodsList.stream().map(goodsDetailVO -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", goodsDetailVO.getGoodsId().toString());
            map.put("openid", openId);
            map.put("template_cover_image", goodsDetailVO.getUrl());
            map.put("scenicname", goodsDetailVO.getScenicName());
            map.put("shoottime", DateUtil.format(goodsDetailVO.getCreateTime(), "yyyy-MM-dd HH:mm"));
            map.put("ossurldm", goodsDetailVO.getVideoUrl());
            return map;
        }).collect(Collectors.toList());
        response
                .put("isgen", taskStatusVO.getStatus() == 1 ? 0 : 1)
                .put("newvideo", videoList)
                .put("newuservideo", userVideoList);
        redisTemplate.opsForValue().set("ly:"+openId, JSON.toJSONString(response), 5, TimeUnit.SECONDS);
        log.info("> {}", response);
        return response;
    }
}
