package com.fdkankan.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.JwtUtil;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.ucenter.common.PageInfo;
import com.fdkankan.ucenter.common.Result;
import com.fdkankan.ucenter.common.constants.ConstantFilePath;
import com.fdkankan.ucenter.common.constants.ResultCodeMsg;
import com.fdkankan.ucenter.entity.*;
import com.fdkankan.ucenter.service.*;
import com.fdkankan.ucenter.vo.RelicsSceneInitQueueDTO;
import com.fdkankan.ucenter.vo.request.LaserSceneParam;
import com.fdkankan.ucenter.vo.request.SceneParam;
import com.fdkankan.ucenter.vo.response.LaserSceneInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Date;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * TODO
 * </p>
 *
 * @author dengsixing
 * @since 2022/9/27
 **/
@Slf4j
@Service
public class InnerServiceImpl implements IInnerService {

    @Autowired
    private ISceneProService sceneProService;
    @Autowired
    private ISceneProEditService sceneProEditService;
    @Autowired
    private IScenePlusService scenePlusService;
    @Autowired
    private IScenePlusExtService scenePlusExtService;
    @Autowired
    private ISceneEditInfoService sceneEditInfoService;
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ICameraDetailService cameraDetailService;
    @Autowired
    private ICameraService cameraService;

    @Autowired
    private FYunFileServiceInterface fYunFileService;

    @Override
    public Result createTokenByNum(String num) {

        Long userId = null;
        ScenePro scenePro = sceneProService.getByNum(num);
        if(Objects.nonNull(scenePro)){
            userId = scenePro.getUserId();
        }else{
            ScenePlus scenePlus = scenePlusService.getByNum(num);
            if(Objects.isNull(scenePlus)){
                return Result.failure("场景为空");
            }
            userId = scenePlus.getUserId();
        }
        User user = userService.getById(userId);
        String token = JwtUtil.createJWT(-1, user.getUserName(), "user");
        String redisKey = String.format(RedisKey.TOKEN_V3,token);
        redisUtil.set(redisKey, JSON.toJSONString(user), RedisKey.EXPIRE_TIME_2_HOUR);

        JSONObject object = new JSONObject();
        object.put("token", token);

        return Result.success(object);
    }

    @Override
    public String getSceneNumVersion(String num) {
        String version = null;
        ScenePro scenepro = sceneProService.getByNum(num);
        if(scenepro == null){
            ScenePlus plus = scenePlusService.getByNum(num);
            if(plus != null){
                version = "V4";
            }
        }else {
            version = "V3";
        }
        return version;
    }

    @Override
    public String querySceneDataSource(String num) {

        String dataSource = null;
        ScenePro scenePro = sceneProService.getByNum(num);
        if(Objects.isNull(scenePro)){
            ScenePlus scenePlus = scenePlusService.getByNum(num);
            if(Objects.isNull(scenePlus)){
                return Result.failure(ErrorCode.FAILURE_CODE_5005.code(), ErrorCode.FAILURE_CODE_5005.message()).toString();
            }
            ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
            dataSource = scenePlusExt.getDataSource();
        }else{
            dataSource = scenePro.getDataSource();
        }
        return  dataSource;
    }

    @Override
    public Result downloadCapture(String num) {

        ScenePro scenePro = sceneProService.getByNum(num);
        ScenePlus scenePlus = scenePlusService.getByNum(num);
        if (ObjectUtils.isEmpty(scenePlus) && ObjectUtils.isEmpty(scenePro)) {
            return Result.failure("场景为空");
        }
        String dataSource = null;
        if(!ObjectUtils.isEmpty(scenePlus)){
            ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
            dataSource = scenePlusExt.getDataSource();
        }else{
            dataSource = scenePro.getDataSource();
        }

        String ossPath = ConstantFilePath.OSS_PREFIX
                + dataSource.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
                .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
        if (!ossPath.endsWith("/")) {
            ossPath = ossPath.concat("/");
        }

        fYunFileService.downloadFileByCommand(dataSource + File.separator + "capture", ossPath);
        return Result.success();
    }

    @Override
    public Result querySceneNum(String path) {
        ScenePro scenePro = sceneProService.findByFileId(path);
        if (!ObjectUtils.isEmpty(scenePro)) {
            return Result.success(scenePro.getNum());
        }
        ScenePlusExt scenePlusExt = scenePlusExtService.getByUnicode(path);
        if (!ObjectUtils.isEmpty(scenePlusExt)) {
            return Result.success(scenePlusService.getById(scenePlusExt.getPlusId()).getNum());
        }
        return Result.success();
    }

    @Override
    public LaserSceneInfoVo getSceneInfo(String num) {
        LaserSceneInfoVo vo = new LaserSceneInfoVo();
        ScenePro scenepro = sceneProService.getByNum(num);
        if(scenepro != null){
            vo.setNum(scenepro.getNum());
            vo.setVersion("V3");
            vo.setSceneSource(scenepro.getSceneSource());
            vo.setSceneScheme(scenepro.getSceneScheme());
            vo.setSceneKind(null);
            vo.setSceneResolution(null);
            vo.setObjScenePath(scenepro.getWebSite());
            vo.setIsObj(scenepro.getIsObj());
            vo.setAlgorithmTime(scenepro.getCreateTime());
            vo.setStatus(scenepro.getStatus());
            vo.setPayStatus(scenepro.getPayStatus());
            vo.setTitle(scenepro.getSceneName());
            SceneProEdit sceneProEdit = sceneProEditService.getByProId(scenepro.getId());
            if(sceneProEdit != null){
                vo.setImgVersion(sceneProEdit.getImagesVersion());
            }
            return vo;
        }

        ScenePlus plus = scenePlusService.getByNum(num);
        if(plus != null){
            ScenePlusExt plusExt = scenePlusExtService.getByPlusId(plus.getId());
            if(plusExt != null){
                vo.setNum(plus.getNum());
                vo.setVersion("V4");
                vo.setSceneSource(plus.getSceneSource());
                vo.setSceneScheme(plusExt.getSceneScheme());
                vo.setSceneKind(plusExt.getSceneKind());
                vo.setSceneResolution(plusExt.getSceneResolution());
                vo.setObjScenePath(plusExt.getWebSite());
                vo.setIsObj(plusExt.getIsObj());
                vo.setAlgorithmTime(plusExt.getAlgorithmTime());
                vo.setStatus(plus.getSceneStatus());
                vo.setPayStatus(plus.getPayStatus());
                vo.setTitle(plus.getTitle());
                SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(plus.getId());
                if(sceneEditInfo != null){
                    vo.setImgVersion(sceneEditInfo.getImgVersion());
                }
                return vo;
            }
        }
        throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400002, ResultCodeMsg.FAILURE_MSG_400002);
    }


    @Override
    public Object getCameraDetail(String snCode) {
        Camera camera = cameraService.getBySnCode(snCode);
        if(camera == null){
            throw new BusinessException(-1,"相机不存在");
        }
        return cameraDetailService.getByCameraId(camera.getId());
    }


    @Override
    public Object getSceneBySnCode(SceneParam param) {
        Camera camera = cameraService.getBySnCode(param.getSnCode());
        if(camera == null ){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400017, ResultCodeMsg.FAILURE_MSG_400017);
        }
        CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId());
        if(cameraDetail == null ){
            throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400017, ResultCodeMsg.FAILURE_MSG_400017);
        }
        LambdaQueryWrapper<ScenePlus> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ScenePlus::getCameraId,camera.getId());
        if(param.getSceneSource() != null){
            wrapper.eq(ScenePlus::getSceneSource,param.getSceneSource());
        }
        List<ScenePlus> list = scenePlusService.list(wrapper);
        if(list.isEmpty()){
            return new ArrayList<>();
        }
        List<Long> plusIds = list.stream().map(ScenePlus::getId).collect(Collectors.toList());
        List<Long> userIds = list.stream().map(ScenePlus::getUserId).collect(Collectors.toList());

        LambdaQueryWrapper<ScenePlusExt> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(ScenePlusExt::getPlusId,plusIds);
        if(param.getLocation() != null){
            wrapper1.eq(ScenePlusExt::getLocation,param.getLocation());
        }
        HashMap<Long,ScenePlus> map = new HashMap<>();
        HashMap<Long, User> userMap = userService.getByIds(userIds);

        list.forEach(e ->map.put(e.getId(),e) );
        List<ScenePlusExt> extList = scenePlusExtService.list(wrapper1);

        List<RelicsSceneInitQueueDTO> voList = new ArrayList<>(extList.size());
        for (ScenePlusExt scenePlusExt : extList) {
            ScenePlus scenePlus = map.get(scenePlusExt.getPlusId());
            if(scenePlus == null){
                continue;
            }
            User user = userMap.get(scenePlus.getUserId());
            RelicsSceneInitQueueDTO dto = getRelicsSceneInitQueueDTO(param, scenePlusExt, scenePlus,user);
            voList.add(dto);
        }
        return voList;
    }

    private  RelicsSceneInitQueueDTO getRelicsSceneInitQueueDTO(SceneParam param, ScenePlusExt scenePlusExt, ScenePlus scenePlus,User user) {
        RelicsSceneInitQueueDTO dto = new RelicsSceneInitQueueDTO();
        dto.setSceneCode(scenePlus.getNum());
        dto.setLocation(scenePlusExt.getLocation());
        dto.setSceneSource(scenePlus.getSceneSource());
        dto.setAlgorithmTime(scenePlusExt.getAlgorithmTime());
        dto.setCreateTime(scenePlus.getCreateTime());
        if(user!=null){
            dto.setPhoneNum(user.getUserName());
        }
        dto.setUserId(scenePlus.getUserId());
        dto.setSnCode(param.getSnCode());
        dto.setStatus(scenePlus.getSceneStatus());
        if(scenePlus.getSceneStatus() ==-2){
            dto.setStatus(1);
        }
        dto.setSceneName(scenePlus.getTitle());
        dto.setShootCount(scenePlusExt.getShootCount());
        return dto;
    }

    @Override
    public Object getSceneByToken(LaserSceneParam param, String token) {
        String username = JwtUtil.getUsername(token);
        if(StringUtils.isBlank(username)){
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        User user = userService.getByUserName(username);
        if(user == null){
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        param.setUserId(user.getId());
        Page<RelicsSceneInitQueueDTO> page = scenePlusService.pageLaserScene(new Page<>(param.getPageNum(),param.getPageSize()),param);


        return PageInfo.PageInfo(page);
    }
}
