package com.ycwl.basic.service.impl.mobile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.biz.TaskStatusBiz;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.mapper.*;
import com.ycwl.basic.model.mobile.goods.*;
import com.ycwl.basic.model.mobile.order.PriceObj;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
import com.ycwl.basic.model.pc.video.req.VideoReqQuery;
import com.ycwl.basic.model.pc.video.resp.VideoRespVO;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.VideoTaskRepository;
import com.ycwl.basic.service.mobile.GoodsService;
import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.service.task.TaskService;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author：longbinbin
 * @Date：2024/12/5 15:04
 */
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private SourceMapper sourceMapper;
    @Autowired
    private ScenicMapper scenicMapper;
    @Autowired
    private FaceMapper faceMapper;
    @Autowired
    private TemplateRepository templateRepository;
    @Autowired
    private VideoTaskRepository videoTaskRepository;
    @Autowired
    private TaskService taskTaskService;
    @Autowired
    private ScenicRepository scenicRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderBiz orderBiz;
    @Autowired
    private FaceRepository faceRepository;
    @Autowired
    private TaskStatusBiz taskStatusBiz;

    public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
        //查询原素材
        List<GoodsPageVO> goodsList = new ArrayList<>();
        VideoReqQuery videoReqQuery = new VideoReqQuery();
        videoReqQuery.setScenicId(query.getScenicId());
        videoReqQuery.setIsBuy(query.getIsBuy());
        videoReqQuery.setFaceId(query.getFaceId());
        videoReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
        //查询成片vlog
        List<VideoRespVO> videoList = videoMapper.queryByRelation(videoReqQuery);
        videoList.forEach(videoRespVO -> {
            GoodsPageVO goodsPageVO = new GoodsPageVO();
            goodsPageVO.setGoodsName(videoRespVO.getTemplateName());
            goodsPageVO.setScenicId(videoRespVO.getScenicId());
            goodsPageVO.setScenicName(videoRespVO.getScenicName());
            goodsPageVO.setGoodsType(0);
            goodsPageVO.setFaceId(videoRespVO.getFaceId());
            goodsPageVO.setGoodsId(videoRespVO.getId());
            goodsPageVO.setTemplateName(videoRespVO.getTemplateName());
            goodsPageVO.setTemplateCoverUrl(videoRespVO.getTemplateCoverUrl());
            goodsList.add(goodsPageVO);
        });

        SourceReqQuery sourceReqQuery = new SourceReqQuery();
        sourceReqQuery.setScenicId(query.getScenicId());
        sourceReqQuery.setIsBuy(query.getIsBuy());
        sourceReqQuery.setFaceId(query.getFaceId());
        sourceReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
        //查询源素材
        List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery);
        ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(query.getScenicId());
        List<GoodsPageVO> sourceGoods = sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getFaceId)).entrySet().stream().flatMap((faceEntry) -> {
            Long faceId = faceEntry.getKey();
            List<SourceRespVO> goods = faceEntry.getValue();
            return goods.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).keySet().stream().filter(type -> {
                if (Integer.valueOf(1).equals(type)) {
                    if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
                        return false;
                    }
                } else if (Integer.valueOf(2).equals(type)) {
                    if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceImage())) {
                        return false;
                    }
                }
                return true;
            }).map(type -> {
                GoodsPageVO goodsPageVO = new GoodsPageVO();
                goodsPageVO.setTemplateCoverUrl(goods.get(0).getUrl());
                goodsPageVO.setFaceId(faceId);
                if (type == 1) {
                    goodsPageVO.setGoodsName("录像集");
                    goodsPageVO.setGoodsType(1);
                } else {
                    goodsPageVO.setGoodsName("照片集");
                    goodsPageVO.setGoodsType(2);
                }
                goodsPageVO.setScenicId(query.getScenicId());
                return goodsPageVO;
            });
        }).collect(Collectors.toList());
        if (!sourceGoods.isEmpty()) {
            if (goodsList.size() > 2) {
                goodsList.addAll(2, sourceGoods);
            } else {
                goodsList.addAll(sourceGoods);
            }
        }
        return ApiResponse.success(goodsList);
    }

    @Override
    public List<GoodsDetailVO> sourceGoodsList(GoodsReqQuery query) {
        FaceEntity face = faceRepository.getFace(query.getFaceId());
        if (face == null) {
            return Collections.emptyList();
        }
        Integer sourceType = query.getSourceType();
        SourceReqQuery sourceReqQuery = new SourceReqQuery();
        sourceReqQuery.setScenicId(query.getScenicId());
        sourceReqQuery.setIsBuy(query.getIsBuy());
        sourceReqQuery.setMemberId(face.getMemberId());
        sourceReqQuery.setType(sourceType);
        sourceReqQuery.setFaceId(query.getFaceId());
        List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
        List<GoodsDetailVO> goodsDetailVOList = new ArrayList<>();

        String goodsNamePrefix = "";
        if (sourceType == 1) {
            goodsNamePrefix = "录像";
        } else if (sourceType == 2) {
            goodsNamePrefix = "图片";
        } else {
            goodsNamePrefix = "其他类型";
        }
        //图片编号
        int i=1;
        for (SourceRespVO sourceRespVO : list) {
            GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
            goodsDetailVO.setGoodsId(sourceRespVO.getId());
            String shootingTime = DateUtils.format(sourceRespVO.getCreateTime(), "yyyy.MM.dd HH:mm:ss");
            if (i < 10) {
                goodsDetailVO.setGoodsName(goodsNamePrefix + "0" + i + " " + shootingTime);
            } else {
                goodsDetailVO.setGoodsName(goodsNamePrefix + i + " " + shootingTime);
            }
            goodsDetailVO.setScenicId(sourceRespVO.getScenicId());
            goodsDetailVO.setScenicName(sourceRespVO.getScenicName());
            goodsDetailVO.setLongitude(sourceRespVO.getLongitude());
            goodsDetailVO.setLatitude(sourceRespVO.getLatitude());
            goodsDetailVO.setGoodsType(sourceType);
            goodsDetailVO.setSourceType(sourceType);
            goodsDetailVO.setGoodsId(sourceRespVO.getId());
            goodsDetailVO.setVideoUrl(sourceRespVO.getVideoUrl());
            goodsDetailVO.setUrl(sourceRespVO.getUrl());
            goodsDetailVO.setCreateTime(sourceRespVO.getCreateTime());
            goodsDetailVO.setIsFree(sourceRespVO.getIsFree());
            goodsDetailVOList.add(goodsDetailVO);
            i++;
        }

        return goodsDetailVOList;
    }

    @Override
    public ApiResponse<VideoGoodsDetailVO> videoGoodsDetail(Long userId, Long videoId) {
        VideoGoodsDetailVO goodsDetailVO = new VideoGoodsDetailVO();
        VideoRespVO videoRespVO = videoMapper.getById(videoId);
        if (videoRespVO == null) {
            return ApiResponse.fail("该vlog不存在或已失效");
        }
        goodsDetailVO.setGoodsName(videoRespVO.getTemplateName());
        goodsDetailVO.setScenicId(videoRespVO.getScenicId());
        goodsDetailVO.setScenicName(videoRespVO.getScenicName());
        goodsDetailVO.setGoodsType(0);
        goodsDetailVO.setGoodsId(videoRespVO.getId());
        goodsDetailVO.setVideoUrl(videoRespVO.getVideoUrl());
        goodsDetailVO.setTemplateCoverUrl(videoRespVO.getTemplateCoverUrl());
        goodsDetailVO.setCreateTime(videoRespVO.getCreateTime());
        goodsDetailVO.setHeight(videoRespVO.getHeight());
        goodsDetailVO.setWidth(videoRespVO.getWidth());
        goodsDetailVO.setDuration(videoRespVO.getDuration());
        if (userId == null) {
            goodsDetailVO.setIsBuy(0);
            goodsDetailVO.setShare(true);
            goodsDetailVO.setPrice("未登录");
        } else {
            MemberVideoEntity entity = videoMapper.queryUserVideo(userId, videoId);
            if (entity == null) {
                goodsDetailVO.setIsBuy(0);
                goodsDetailVO.setShare(true);
                goodsDetailVO.setPrice("未登录");
            } else {
                goodsDetailVO.setShare(false);
                goodsDetailVO.setFaceId(entity.getFaceId());
                goodsDetailVO.setIsBuy(entity.getIsBuy());
                if (Integer.valueOf(0).equals(entity.getIsBuy())) {
                    PriceObj priceObj = orderBiz.queryPrice(videoRespVO.getScenicId(), 0, videoId);
                    if (priceObj.isFree()) {
                        goodsDetailVO.setIsBuy(1);
                    } else {
                        goodsDetailVO.setIsBuy(0);
                        goodsDetailVO.setPrice(priceObj.getPrice().toString());
                        goodsDetailVO.setSlashPrice(priceObj.getSlashPrice().toString());
                    }
                }
            }
        }
        TaskEntity task = videoTaskRepository.getTaskById(videoRespVO.getTaskId());
        JSONObject paramJson = JSON.parseObject(task.getTaskParams());
        long deviceCount;
        goodsDetailVO.setShotTime(taskTaskService.getTaskShotDate(task.getId()));
        if (paramJson == null) {
            deviceCount = 1;
        } else {
            List<String> templatePlaceholder = templateRepository.getTemplatePlaceholder(task.getTemplateId());
            deviceCount = paramJson.keySet().stream()
                    .filter(StringUtils::isNumeric)
                    .filter(templatePlaceholder::contains)
                    .count();
        }
        goodsDetailVO.setLensNum((int) deviceCount);
        return ApiResponse.success(goodsDetailVO);
    }

    /**
     * 查询用户当前景区的视频合成任务状态
     *
     * @param faceId 景区id
     * @return 0没有任务 1 合成中 2 合成成功
     */
    @Override
    public VideoTaskStatusVO getTaskStatusByFaceId(Long faceId) {
        FaceEntity face = faceRepository.getFace(faceId);
        Long userId = face.getMemberId();
        VideoTaskStatusVO response = new VideoTaskStatusVO();
        response.setFaceId(faceId);
        if (face == null) {
            response.setStatus(0);
            return response;
        }
        response.setScenicId(face.getScenicId());
        int faceCutStatus = taskStatusBiz.getFaceCutStatus(faceId);
        response.setCutStatus(faceCutStatus);
        if (faceCutStatus == 0) {
            // 切视频中，也显示正在处理
            response.setStatus(2);
            return response;
        }
        List<MemberVideoEntity> taskList = videoMapper.listRelationByFace(userId, faceId);
        if (faceCutStatus != 1 && taskList.isEmpty()) {
            // 视频切成了能够获取视频的状态，但是没有任务，还是显示正在处理
            response.setStatus(0);
            return response;
        }
        if (taskList.isEmpty()) {
            response.setStatus(0);
            return response;
        }
        List<TemplateRespVO> templateList = templateRepository.getTemplateListByScenicId(response.getScenicId());
        List<Long> templateIds = templateList.stream().map(TemplateRespVO::getId).collect(Collectors.toList());
        response.setMaxCount(templateList.size());
        List<MemberVideoEntity> notFinishedTasks = taskList.stream()
                .filter(task -> templateIds.contains(task.getTemplateId()))
                .filter(task -> {
                    TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
                    if (taskById == null) {
                        return true;
                    }
                    return taskById.getStatus() == 0 || taskById.getStatus() == 2;
                })
                .collect(Collectors.toList());
        long finishedTask = taskList.stream()
                .filter(task -> {
                    TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
                    if (taskById == null) {
                        return false;
                    }
                    return taskById.getStatus() == 1;
                }).count();
        response.setCount(finishedTask);
        if (!notFinishedTasks.isEmpty()) {
            response.setTemplateId(notFinishedTasks.get(0).getTemplateId());
            response.setTaskId(notFinishedTasks.get(0).getTaskId());
            response.setStatus(2);
            return response;
        }
        MemberVideoEntity lastVideo = taskList.get(taskList.size() - 1);
        response.setTaskId(lastVideo.getTaskId());
        response.setTemplateId(lastVideo.getTemplateId());
        response.setVideoId(lastVideo.getVideoId());
        response.setStatus(1);
        return response;
    }

    @Override
    public VideoTaskStatusVO getAllTaskStatus(Long userId) {
        FaceRespVO lastFaceByUserId = faceMapper.findLastFaceByUserId(String.valueOf(userId));
        return getTaskStatusByFaceId(lastFaceByUserId.getId());
    }

    @Override
    public VideoTaskStatusVO getTaskStatusByTemplateId(Long faceId, Long templateId) {
        List<MemberVideoEntity> taskList = videoMapper.listRelationByFaceAndTemplate(faceId, templateId);
        VideoTaskStatusVO response = new VideoTaskStatusVO();
        response.setFaceId(faceId);
        response.setTemplateId(templateId);
        if (taskList.isEmpty()) {
            response.setStatus(0);
            return response;
        }
        response.setScenicId(taskList.get(0).getScenicId());
        response.setMaxCount(templateRepository.getTemplateListByScenicId(response.getScenicId()).size());
        List<MemberVideoEntity> notFinishedTasks = taskList.stream()
                .filter(task -> {
                    TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
                    if (taskById == null) {
                        return true;
                    }
                    return taskById.getStatus() == 0 || taskById.getStatus() == 2;
                }).collect(Collectors.toList());
        long finishedTask = taskList.stream()
                .filter(task -> {
                    TaskEntity taskById = videoTaskRepository.getTaskById(task.getTaskId());
                    if (taskById == null) {
                        return false;
                    }
                    return taskById.getStatus() == 1;
                }).count();
        response.setCount(finishedTask);
        int faceCutStatus = taskStatusBiz.getFaceCutStatus(faceId);
        if (Integer.valueOf(0).equals(faceCutStatus)) {
            response.setTemplateId(notFinishedTasks.get(0).getTemplateId());
            response.setStatus(2);
            return response;
        }
        if (!notFinishedTasks.isEmpty()) {
            response.setTemplateId(notFinishedTasks.get(0).getTemplateId());
            response.setTaskId(notFinishedTasks.get(0).getTaskId());
            response.setStatus(2);
            return response;
        }
        MemberVideoEntity lastVideo = taskList.get(taskList.size() - 1);
        response.setTaskId(lastVideo.getTaskId());
        response.setTemplateId(lastVideo.getTemplateId());
        response.setVideoId(lastVideo.getVideoId());
        if (null != lastVideo.getVideoId()) {
            response.setStatus(1);
            response.setVideoId(lastVideo.getVideoId());
        } else {
            TaskEntity taskById = videoTaskRepository.getTaskById(lastVideo.getTaskId());
            if (taskById == null) {
                response.setStatus(1);
            } else {
                if (taskById.getStatus() == 1) {
                    response.setStatus(1);
                    response.setVideoId(lastVideo.getVideoId());
                } else if (taskById.getStatus() == 0 || taskById.getStatus() == 2) {
                    response.setStatus(2);
                } else {
                    response.setStatus(1);
                }
            }
        }
        return response;
    }

    @Override
    public VideoTaskStatusVO getTaskStatusByScenicId(Long userId, Long scenicId) {
        FaceRespVO faceVO = faceMapper.getLatestByMemberId(userId, scenicId);
        VideoTaskStatusVO response = new VideoTaskStatusVO();
        response.setScenicId(scenicId);
        if (faceVO == null) {
            // 从来没露脸
            response.setStatus(-2);
            return response;
        }
        return getTaskStatusByFaceId(faceVO.getId());
    }

    @Override
    public ApiResponse<GoodsDetailVO> sourceGoodsInfo(Long sourceId) {
        SourceRespVO sourceRespVO = sourceMapper.getById(sourceId);
        if (sourceRespVO == null) {
            sourceRespVO = sourceMapper.getById(sourceId);
            if (sourceRespVO == null) {
                return ApiResponse.fail("该视频不存在");
            }
        }
        GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
        goodsDetailVO.setGoodsName("原片");
        goodsDetailVO.setScenicId(sourceRespVO.getScenicId());
        goodsDetailVO.setScenicName(sourceRespVO.getScenicName());
        goodsDetailVO.setGoodsType(sourceRespVO.getType());
        goodsDetailVO.setGoodsId(sourceRespVO.getId());
        goodsDetailVO.setVideoUrl(sourceRespVO.getVideoUrl());
        goodsDetailVO.setTemplateCoverUrl(sourceRespVO.getUrl());
        goodsDetailVO.setCreateTime(sourceRespVO.getCreateTime());
        return ApiResponse.success(goodsDetailVO);
    }

}
