package com.fdkankan.scene.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.RecStatus;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.constant.ZipStatus;
import com.fdkankan.common.util.CreateObjUtil;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.fyun.oss.UploadToOssUtil;
import com.fdkankan.scene.entity.Scene3dfamily;
import com.fdkankan.scene.mapper.IScene3dfamilyMapper;
import com.fdkankan.scene.service.IScene3dfamilyService;
import com.fdkankan.scene.service.ISceneProService;
import com.fdkankan.scene.vo.Scene3dfamilyVO;
import com.fdkankan.scene.vo.SceneEditParamVO;
import com.fdkankan.scene.vo.SceneProVO;
import com.fdkankan.scene.vo.SceneVO;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 三维家表 服务实现类
 * </p>
 *
 * @author dengsixing
 * @since 2021-12-23
 */
@Slf4j
@Service
public class Scene3dfamilyServiceImpl extends ServiceImpl<IScene3dfamilyMapper, Scene3dfamily> implements IScene3dfamilyService {

    private static String DIR_NAME = "downloads/furnished/";

    @Value("${oss.prefix.ali}")
    private String prefixAli;

    @Autowired
    ISceneProService sceneProService;
    @Autowired
    @Qualifier("uploadToOssUtil")
    UploadToOssUtil uploadToOssUtil;


    @Override
    public ResultData createZip(SceneProVO sceneProVo) {
        Scene3dfamily scene3dfamily =
                baseMapper.findSceneCodeByCode(
                        Scene3dfamilyVO
                            .builder()
                            .num(sceneProVo.getNum())
                            .zipStatus(ZipStatus.DOING.code())
                            .build());
        String path = sceneProVo.getDataSource() + "_3df" + File.separator + sceneProVo.getNum();
        try {
            if(scene3dfamily == null){
                throw new BusinessException(ErrorCode.FAILURE_CODE_5032);
            }

            log.info("三维家 信息保存 路径 : " + path);
            //创建文件夹
            FileUtils.createDir(path);

            //生成vision.json
            sceneProService.downloadVisionData(SceneEditParamVO.builder().num(sceneProVo.getNum()).build());
            //拉取data
            CreateObjUtil.ossUtilCp("data" + File.separator + "data" + sceneProVo.getNum()  + File.separator,
                    path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneProVo.getNum());


            //写入 scene.json 改名为 getinfo.json
            SceneVO sceneVo = sceneProService.getInfo(sceneProVo.getNum());

            JSONObject dataJson = (JSONObject) JSONObject.toJSON(sceneVo);

            FileUtils.writeFile(path + File.separator + "scene"  + File.separator + "data" +  File.separator  + "data"
                    + sceneProVo.getNum() + File.separator + "getinfo.json", dataJson.toString());

            //拉取images
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "floorLogoImg.png",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "floorplan.png",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "logo-main.png",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "logo-main-en.png",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "smallPic.jpg",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "thumbBigImg.jpg",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "thumbSmallImg.jpg",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());
            CreateObjUtil.ossUtilCp("images" + File.separator + "images" + sceneProVo.getNum()  + File.separator + "pan",
                    path + File.separator + "scene"  + File.separator + "images" + File.separator + "images" + sceneProVo.getNum());

            //拉取video
            CreateObjUtil.ossUtilCp("video" + File.separator + "video" + sceneProVo.getNum()  + File.separator,
                    path + File.separator + "scene"  + File.separator + "video" + File.separator + "video" + sceneProVo.getNum());

            //拉取voice
            CreateObjUtil.ossUtilCp("voice" + File.separator + "voice" + sceneProVo.getNum()  + File.separator,
                    path + File.separator + "scene"  + File.separator + "voice" + File.separator + "voice" + sceneProVo.getNum());

            //压缩zip
            FileUtils.zipFile(path + ".zip", path);
            log.info("三维家 zip完成 : " + path);

            //上传oss
            // 上传到阿里云sso
            uploadToOssUtil.upload(path + ".zip", DIR_NAME + sceneProVo.getNum() + ".zip");
            log.info("upload success");

            String url = prefixAli + DIR_NAME + sceneProVo.getNum() + ".zip";

            log.info("upload url: {}" + url);

            scene3dfamily.setZipLink(url);
            scene3dfamily.setZipStatus(ZipStatus.SUCCESS.code());
            scene3dfamily.setZipEndTime(new Date());
            scene3dfamily.setUpdateTime(new Date());
            baseMapper.updateById(scene3dfamily);
        }catch (Exception e){
            scene3dfamily.setZipStatus(ZipStatus.FAILD.code());
            scene3dfamily.setZipEndTime(new Date());
            scene3dfamily.setUpdateTime(new Date());
            baseMapper.updateById(scene3dfamily);
            log.error("场景打包失败", e);
        }finally {
            FileUtils.deleteDirectory(path);
            FileUtils.deleteDirectory(path + ".zip");
        }

        return ResultData.ok();
    }

    @Override
    public Scene3dfamily findSceneNumByNum(Scene3dfamilyVO scene3dfamilyVO) {
        return baseMapper.findSceneCodeByCode(scene3dfamilyVO);
    }

    @Override
    public Map<String, String> findSceneNumByNum2(Scene3dfamilyVO scene3dfamilyVO) {
        Map<String, String> result = new HashMap<>();
        result.put("url","");
        result.put("status",ZipStatus.OTHER.code().toString());
        Scene3dfamily scene3dfamily = baseMapper.findSceneCodeByCode(scene3dfamilyVO);
        if(Objects.nonNull(scene3dfamily)){
            result.put("url",scene3dfamily.getZipLink() == null ?"":scene3dfamily.getZipLink());
            result.put("status",scene3dfamily.getZipStatus().toString());
        }
        //验证是否在打包
        return result;
    }

    @Override
    public void updateSceneNumByNum(Scene3dfamily scene3dfamily) {
        this.update(new LambdaUpdateWrapper<Scene3dfamily>()
                .eq(Scene3dfamily::getNum, scene3dfamily.getNum())
                .set(Scene3dfamily::getTbStatus, TbStatus.DELETE.code()));
    }
}
