package fcb.project.manager.core.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import fcb.project.manager.base.entity.*;
import fcb.project.manager.base.enums.AuditStatus;
import fcb.project.manager.base.enums.DeleteStatus;
import fcb.project.manager.base.enums.HouseStatus;
import fcb.project.manager.base.enums.SysUserRoleEnums;
import fcb.project.manager.base.param.house.QueryHouseParam;
import fcb.project.manager.base.service.custom.PanoService;
import fcb.project.manager.base.service.impl.*;
import fcb.project.manager.base.utils.DataUtils;
import fcb.project.manager.base.utils.DateUtil;
import fcb.project.manager.base.utils.ExcelUtil;
import fcb.project.manager.base.vo.house.HouseVO;
import fcb.project.manager.core.feignInterfaces.SceneFeign;
import fdage.back.sdk.base.entity.Result;
import fdage.back.sdk.base.entity.ViewResult;
import fdage.back.sdk.base.enums.ResultCodeEnum;
import fdage.back.sdk.base.exception.CommonBaseException;
import fdage.back.sdk.base.uuid.SnowFlakeUUidUtils;
import fdage.back.sdk.core.alibabaUtils.AlibabaOssHelper;
import io.swagger.annotations.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 2 * @Author: Abner
 * 3 * @Date: 2021/1/7 17:38
 * 4
 */
@Api(tags = "房源相关接口")
@RestController
@RequestMapping("fcb/project/house")
@Log4j2
@Validated
public class HouseManagerController extends BaseController{

    @Autowired
    private TmHouseServiceImpl tmHouseService;

    @Autowired
    private TmAuditServiceImpl tmAuditService;

    @Autowired
    private TmAuditLogServiceImpl tmAuditLogService;

    @Autowired
    private TmEstateServiceImpl tmEstateService;

    @Value("${image.local.path}")
    private String imageLocalPath;

    @Value("${excel.local.path}")
    private String excelLocalPath;

    @Value("${inner.vr.scene.host}")
    private String innerSceneVrHost;

    @Value("${outer.vr.scene.host}")
    private String outerSceneVrHost;

    @Value("${vr.scene.link}")
    private String sceneVrLink;

    @Value("${share.logo.oss.path}")
    private String ossPath;

    @Value("${oss.query.url}")
    private String ossQueryUrl;

    @Autowired
    private AlibabaOssHelper alibabaOssHelper;

    @Autowired
    private TmOperationServiceImpl tmOperationService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PanoService panoService;

    @Autowired
    private SceneFeign sceneFeign;

    public static String IMAGE_PATH = ".+(.JPEG|.jpeg|.JPG|.jpg|.GIF|.gif|.BMP|.bmp|.PNG|.png)";



    @GetMapping("/queryOrSearchList")
    @ApiOperation(value = "根据条件拉取所有房源")
    public ViewResult<HouseVO> getHouseList(QueryHouseParam queryHouseParam) {
        IPage<HouseVO> resultPage = tmEstateService.listProject(queryHouseParam, getContextUserInfo(), getToken());
        return ViewResult.success(DataUtils.assembleResult(resultPage.getTotal(), resultPage.getPages(),
                resultPage.getCurrent(), resultPage.getRecords()));
    }

    @GetMapping("/getAuditHouseList")
    @ApiOperation(value = "审核管理页面根据条件拉取所有房源")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseTitle", value = "房源名称", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态: 0 -> 草稿;1->待集团审核;2->已审核;-1->未通过;3->待地区审核", paramType = "query", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "type", value = "房源类型： 1->新房,2->二手房", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "belongCompany", value = "所属公司ID", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "estateName", value = "楼盘名称", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "startTime", value = "审核开始时间（00：00：00）", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "审核结束时间（23：59：59）", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", paramType = "query", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "query", required = true, dataType = "Long")
    })
    public Result<Object> getAuditHouseList(@RequestParam(required = false) String houseTitle,
                                       @RequestParam(required = false) Integer status,
                                       @RequestParam(required = false , name = "type") Integer type,
                                       @RequestParam(name = "belongCompany") String belongCompany,
                                       @RequestParam(name = "estateName") String estateName,
                                            @RequestParam(name = "startTime") String startTime,
                                            @RequestParam(name = "endTime") String endTime,
                                       @RequestParam(name = "pageNum")Long pageNum,
                                       @RequestParam(name = "pageSize")Long pageSize){
        ContextTokenBean tokenMap = getContextUserInfo();

        IPage<TmHouse> resultPage = tmHouseService.getAuditHouseList(houseTitle , status ,
                type , belongCompany , estateName , getToken() , startTime, endTime,  pageNum , pageSize, tokenMap);
        return  Result.success(DataUtils.assembleResult(resultPage.getTotal(), resultPage.getPages(),
                resultPage.getCurrent(), resultPage.getRecords()));
    }

    @GetMapping("/exportAuditHouseList")
    @ApiOperation(value = "审核管理页面根据条件拉取所有房源")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseTitle", value = "房源名称", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态: 0->草稿;1->待审核;2->已审核;3->未通过", paramType = "query", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "type", value = "房源类型： 1->新房,2->二手房", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "belongCompany", value = "所属公司ID", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "estateName", value = "楼盘名称", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "startTime", value = "审核开始时间（00：00：00）", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "审核结束时间（23：59：59）", paramType = "query", required = true, dataType = "String"),
    })
    public Result exportAuditHouseList(@RequestParam(required = false) String houseTitle,
                                            @RequestParam(required = false) Integer status,
                                            @RequestParam(required = false , name = "type") Integer type,
                                            @RequestParam(name = "belongCompany") String belongCompany,
                                            @RequestParam(name = "estateName") String estateName,
                                            @RequestParam(name = "startTime") String startTime,
                                            @RequestParam(name = "endTime") String endTime,
                                            @RequestParam(name = "pageNum")Long pageNum,
                                            @RequestParam(name = "pageSize")Long pageSize, HttpServletResponse response) throws Exception{
        ContextTokenBean tokenMap = getContextUserInfo();

        List<TmHouse> houseList = tmHouseService.getAuditHouseListAll(houseTitle , status ,
                type , belongCompany , estateName , startTime, endTime, tokenMap);

        //导出的数据
        Map<String, String> item = null;
        List<Map> dataList = new ArrayList<Map>();
        String outType = "";
        String[] AUDIT_EXCEL_COLE_NAME = {"序号","VR项目id","VR项目名称","项目类型","所属楼盘","公司","创建人","提审时间","审核状态","审核人", "审核时间"};
        ExcelUtil excelUtil = new ExcelUtil(Arrays.asList(AUDIT_EXCEL_COLE_NAME));
        int num = 0;
        for(TmHouse house : houseList){
            num += 1;
            //楼盘数据
            item = new HashMap();
            item.put(excelUtil.getColeNames().get(0), String.valueOf(num));
            item.put(excelUtil.getColeNames().get(1), house.getId());
            item.put(excelUtil.getColeNames().get(2), house.getHouseTitle());
            if(house.getType().intValue() == 1){
                item.put(excelUtil.getColeNames().get(3), "新房");
            }
            if(house.getType().intValue() == 2){
                item.put(excelUtil.getColeNames().get(3), "二手房");
            }


            item.put(excelUtil.getColeNames().get(4), house.getEstateName());
            item.put(excelUtil.getColeNames().get(5), house.getBelongCompanyName());
            item.put(excelUtil.getColeNames().get(6), house.getCreateByName());

            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            item.put(excelUtil.getColeNames().get(7), house.getSubmitAuditTime() == null? "" : house.getSubmitAuditTime().format(df));
            if(house.getStatus().compareTo(HouseStatus.WAITING_AUDIT.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.WAITING_AUDIT.getDesc());
            }
            if(house.getStatus().compareTo(HouseStatus.AUDITED.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.AUDITED.getDesc());
            }
            if(house.getStatus().compareTo(HouseStatus.REJECT.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.REJECT.getDesc());
            }
            if(house.getStatus().compareTo(HouseStatus.DRAFT.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.DRAFT.getDesc());
            }
            if(house.getStatus().compareTo(HouseStatus.WAITING_REGION_AUDIT.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.WAITING_REGION_AUDIT.getDesc());
            }
            if(house.getStatus().compareTo(HouseStatus.REGION_REJECT.getCode()) == 0){
                item.put(excelUtil.getColeNames().get(8), HouseStatus.REGION_REJECT.getDesc());
            }
            item.put(excelUtil.getColeNames().get(8), house.getAuditorName());
            item.put(excelUtil.getColeNames().get(8), house.getAuditTime() == null? "" : house.getAuditTime().format(df));

            dataList.add(item);
        }

        String date = DateUtil.date2String(new Date(), DateUtil.YYYYMMDDHHMMSS_DATA_FORMAT);

        String aduitName = "";
        if(status.compareTo(HouseStatus.ALL.getCode()) == 0){
            aduitName = HouseStatus.ALL.getDesc();
        }
        if(status.compareTo(HouseStatus.WAITING_AUDIT.getCode()) == 0){
            aduitName = HouseStatus.WAITING_AUDIT.getDesc();
        }
        if(status.compareTo(HouseStatus.AUDITED.getCode()) == 0){
            aduitName = HouseStatus.AUDITED.getDesc();
        }
        if(status.compareTo(HouseStatus.REJECT.getCode()) == 0){
            aduitName = "未通过";
        }
        if(status.compareTo(HouseStatus.WAITING_REGION_AUDIT.getCode()) == 0){
            aduitName = HouseStatus.WAITING_REGION_AUDIT.getDesc();
        }
        String dateStr = "VR看房审核管理-" + aduitName + "-" + date;
        String fileName = dateStr + ".xls";
        File file = new File(excelLocalPath + fileName);
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }

        excelUtil.writeExcel(dataList, excelUtil.getColeNames().size(), excelLocalPath + fileName, dateStr);
        return Result.success((Object) (outerSceneVrHost + "excel/" + dateStr + ".xls"));
    }


    @GetMapping("/exportProjectList")
    @ApiOperation(value = "vr项目导出")
    public ViewResult<String> exportProjectList(QueryHouseParam queryHouseParam) throws Exception{
        String url = tmEstateService.exportProjectList(queryHouseParam, getContextUserInfo(), getToken());
        return ViewResult.success(url);
    }


    @GetMapping("/getShareLinks")
    @ApiOperation(value = "根据房源ID获取房源所有分享链接")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> getShareLinks(@RequestParam(required = true) String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        List<PanoInitSceneBean> sceneRspList  = panoService.getAllTypeSceneNums(houseId , getToken());
        return Result.success(sceneRspList);
    }

    @GetMapping("/getQrImage")
    @ApiOperation(value = "根据房源ID获取房源分享二维码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> getQrImage(@RequestParam(required = true) String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        if(StringUtils.isBlank(tmHouse.getSceneNum())){
            return Result.failure("该房源未生成场景码");
        }
        String path = panoService.getOneVrLink(houseId , getToken());
        if(StringUtils.isBlank(path)){
            return Result.failure("可分享的链接未生成");
        }
        String newOuterSceneVrHost = outerSceneVrHost.substring(0 , outerSceneVrHost.length() - 1);
        String totalVrUrl = newOuterSceneVrHost + path;
        log.info("将要生成二维码的链接为:{}" , totalVrUrl);
        String totalOssQueryPath = "";
        if(!StringUtils.equals(path , tmHouse.getVrPath())){
            //720返回的vr路径有变动，则需要更新
            String localPath = imageLocalPath + "logo.png";
            String outPutImageName = System.currentTimeMillis() + ".jpg";
            String outPutImageResultPath = imageLocalPath + outPutImageName;
            File localPathFile = new File(localPath);
            try {
                if(!DataUtils.createQRCode(totalVrUrl ,  outPutImageResultPath , localPathFile)){
                    log.info("生成分享二维码失败");
                    return Result.failure("生成分享二维码失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.info("生成分享二维码出现异常");
                return Result.failure("生成分享二维码出现异常");
            }
            String resultOssPath = ossPath + outPutImageName;
            alibabaOssHelper.doUploadThenDelete(outPutImageResultPath , resultOssPath);
            totalOssQueryPath = ossQueryUrl + resultOssPath;

            tmHouse.setQrCode(totalOssQueryPath);
            tmHouse.setUpdateTime(LocalDateTime.now());
            tmHouse.setVrPath(path);
            tmHouseService.updateHouse(tmHouse);
        }else{
            totalOssQueryPath = tmHouse.getQrCode();
        }
        Map<String , Object> resultMap = new HashMap<>();
        resultMap.put("QrCode" , totalOssQueryPath);
        resultMap.put("vrLink" , totalVrUrl);
        return Result.success(resultMap);

    }

    @ApiOperation(value = "上传照片并生成分享二维码")
    @PostMapping("/uploadImage")
    public Result uploadIntroduceVideo(@RequestParam("file") MultipartFile file , @RequestParam(required = true) String houseId) {
        if (null == file) {
            return Result.failure("文件缺失");
        }
        Pattern pattern = Pattern.compile(IMAGE_PATH);
        Matcher matcher = pattern.matcher(file.getOriginalFilename());
        if(!matcher.find()){
            return Result.failure("只能上传照片格式的文件");
        }
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        if(StringUtils.isBlank(tmHouse.getSceneNum())){
            return Result.failure("该房源未生成场景码");
        }
        int index = file.getOriginalFilename().indexOf(".");
        String newFileName = System.currentTimeMillis() + "";
        if(index != -1){
            newFileName = newFileName + file.getOriginalFilename().substring(index);
        }
        if(StringUtils.isBlank(newFileName)){
            return Result.failure("获取文件后缀名失败");
        }
        String fullLocalImagePath = imageLocalPath.concat(newFileName);
        log.info("照片文件下载到本地路径为:{}", fullLocalImagePath);
        File totalFile = new File(fullLocalImagePath);
        if(totalFile.exists()){
            totalFile.delete();
        }
        try {
            file.transferTo(totalFile);
        } catch (IOException e) {
            e.printStackTrace();
            log.info("照片文件已经下载到本地出现异常:{}", e);
            return Result.failure("下载文件出现异常");
        }
        if(!totalFile.exists()){
            log.info("下载文件失败:{}" , fullLocalImagePath);
            return Result.failure("上传文件失败");
        }
        String path = panoService.getOneVrLink(houseId , getToken());
        if(StringUtils.isBlank(path)){
            return Result.failure("可分享的链接未生成");
        }
        String newOuterSceneVrHost = outerSceneVrHost.substring(0 , outerSceneVrHost.length() - 1);
        String totalVrUrl = newOuterSceneVrHost + path;
        log.info("将要生成二维码的链接为:{}" , totalVrUrl);
        String outPutImageName = System.currentTimeMillis() + ".jpg";
        String outPutImageResultPath = imageLocalPath + outPutImageName;
        try {
            if(!DataUtils.createQRCode(totalVrUrl ,  outPutImageResultPath , totalFile)){
                return Result.failure("生成分享二维码失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("生成分享二维码出现异常");
            return Result.failure("生成分享二维码出现异常");
        }
        String resultOssPath = ossPath + outPutImageName;
        alibabaOssHelper.doUploadThenDelete(outPutImageResultPath , resultOssPath);
        String totalOssQueryPath = ossQueryUrl + resultOssPath;

        tmHouse.setQrCode(totalOssQueryPath);
        tmHouse.setUpdateTime(LocalDateTime.now());
        if(!StringUtils.equals(tmHouse.getVrPath() , path)){
            tmHouse.setVrPath(path);
        }
        tmHouseService.updateHouse(tmHouse);

        int ins = tmOperationService.addNewWithTypeAndContent(getContextUserInfo() , "VR楼盘项目" , "更新VR项目分享二维码/" + tmHouse.getHouseTitle());
        if(ins != 1){
            log.info("插入操作记录失败");
        }

        Map<String , Object> resultMap = new HashMap<>();
        resultMap.put("QrCode" , totalOssQueryPath);
        resultMap.put("vrLink" , totalVrUrl);
        return Result.success(resultMap);
    }



    @GetMapping("/getHouseDetail")
    @ApiOperation(value = "根据房源ID获取房源详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> getHouseDetail(@RequestParam(required = true) String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        return Result.success(tmHouse);

    }

    @GetMapping("/canEdit")
    @ApiOperation(value = "根据房源ID获取房源详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> canEdit(@RequestParam(required = true) String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        if(tmHouse.getStatus().compareTo(HouseStatus.WAITING_AUDIT.getCode()) == 0 ||
                tmHouse.getStatus().compareTo(HouseStatus.AUDITED.getCode()) == 0){
            Result.success(false);
        }
        return Result.success(true);

    }

    @GetMapping("/houseDetailWithoutAuth")
    @ApiOperation(value = "根据房源ID获取房源详情-无需授权，给H5使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> houseDetailWithoutAuth(@RequestParam(required = true) String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse tmHouse = tmHouseService.getById(houseId);
        if(null == tmHouse || tmHouse.getIsDelete().compareTo(1) == 0){
            return Result.failure("房源不存在");
        }
        return Result.success(tmHouse);

    }


    @GetMapping("/getEstateDetail")
    @ApiOperation(value = "根据楼盘ID获取楼盘详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "estateId", value = "楼盘ID", paramType = "query", required = true, dataType = "String"),
    })
    public Result<Object> getEstateDetail(@RequestParam(required = true) String estateId){
        if(StringUtils.isBlank(estateId)){
            return Result.failure("楼盘ID不能为空");
        }
        TmEstate tmEstate = tmEstateService.getById(estateId);
        if(null == tmEstate){
            return Result.failure("楼盘不存在");
        }
        return Result.success(tmEstate);

    }

    @PostMapping("/addHouse")
    @ApiOperation(value = "创建默认房源")
    public ViewResult addNewHouse(@RequestBody TmEstate tmEstate){
        Map<String, Object> map = tmEstateService.addProject(tmEstate, getContextUserInfo());
        return ViewResult.success(map);
    }

    @PostMapping("/updateVrLink")
    @ApiOperation(value = "更新房源的VRLINK-这里需要720或者四维看看微服务创建完成调用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "vrLink", value = "场景vrlink", paramType = "query", required = false, dataType = "String"),
    })
    public Result<Object> updateVrLink(@RequestParam String houseId ,
                                       @RequestParam String vrLink){
        if(!StringUtils.isNoneBlank(houseId , vrLink)){
            return Result.failure("房源ID或者VRLINK为空了");
        }
        TmHouse dbHouse = tmHouseService.getById(houseId);
        if(null == dbHouse){
            return Result.failure("房源不存在");
        }
        dbHouse.setVrLink(vrLink);
        if(tmHouseService.updateHouse(dbHouse)){
            return Result.success("更新成功");
        }
        return Result.failure("更新失败");
    }


    @PostMapping("/deleteHouse")
    @ApiOperation(value = "删除房源信息")
    public ViewResult deleteHouse(@ApiParam(name="estateId", value = "楼盘id")
                                      @NotBlank(message = "楼盘id不能为空")
                                      @RequestParam("estateId") String estateId){
        String msg = tmEstateService.delete(estateId, getContextUserInfo(), getToken());
        return ViewResult.success(msg);
    }


    @PostMapping("/updateHouse")
    @ApiOperation(value = "修改房源信息")
    public Result<Object> updateHouse(@RequestBody TmHouse tmHouse){

        if(null == tmHouse){
            return Result.failure("入参为空");
        }
        if(StringUtils.isBlank(tmHouse.getId())){
            return Result.failure("id不能为空");
        }
        TmHouse dbHouse = tmHouseService.getById(tmHouse.getId());
        if(null == dbHouse){
            return Result.failure("房源不存在");
        }
        if(StringUtils.isBlank(dbHouse.getSceneNum()) && StringUtils.isNotBlank(tmHouse.getSceneNum())){
            //新增场景码，这时候需要生成内网和外网场景码的链接
            if(StringUtils.isBlank(tmHouse.getFcbHouseId())){
                return Result.failure("更新场景码必须上送房车宝的房源ID");
            }
            String innerHostVrLink = innerSceneVrHost + sceneVrLink + tmHouse.getSceneNum() + "&prodId=" + tmHouse.getFcbHouseId()
                    + "&houseId=" + tmHouse.getId();
            String outerHostVrLink = outerSceneVrHost + sceneVrLink + tmHouse.getSceneNum() + "&prodId=" + tmHouse.getFcbHouseId()
                    + "&houseId=" + tmHouse.getId();
            tmHouse.setVrLink(outerHostVrLink);
            tmHouse.setInnerVrLink(innerHostVrLink);
        }

        if(tmHouseService.updateHouse(tmHouse)){
            ContextTokenBean contextTokenBean = getContextUserInfo();
            if(null != contextTokenBean){
                int ins = tmOperationService.addNewWithTypeAndContent(getContextUserInfo() , "VR楼盘项目" , "更新VR项目/" + dbHouse.getHouseTitle());
                if(ins != 1){
                    log.info("插入操作记录失败");
                }
            }
            return Result.success("修改成功");
        }else{
            return Result.failure("修改失败");
        }
    }

    @PostMapping("/submitAudit")
    @ApiOperation(value = "提交审核记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> addNewAudit(HttpServletRequest request ,  @RequestParam String houseId){

        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse dbHouse = tmHouseService.getById(houseId);
        if(null == dbHouse || null == dbHouse.getStatus()){
            return Result.failure("房源不存在或者房源状态非法");
        }

        if(HouseStatus.AUDITED.getCode().compareTo(dbHouse.getStatus()) == 0){
            return Result.failure("房源已审核");
        }

        if(StringUtils.isBlank(dbHouse.getEstateId())){
            return Result.failure("房源未分配所属的楼盘不存在");
        }
        ContextTokenBean tokenMap =  getContextUserInfo();
        TmEstate tmEstate = tmEstateService.getById(dbHouse.getEstateId());
        if(null == tmEstate){
            return Result.failure("房源所属的楼盘不存在");
        }

        TmAuditLog tmAuditLog = new TmAuditLog();
        TmAudit tmAudit = tmAuditService.addNewAuditWithRespon(dbHouse , tmEstate , tokenMap);
        if(tmAudit != null){
            dbHouse = tmHouseService.selectForUpdate(dbHouse.getId());
            if(null == dbHouse){
                log.error("抢锁失败，更新房源的审批记录失败");
                throw new CommonBaseException(ResultCodeEnum.D101 , "抢锁失败");
            }
            dbHouse.setAuditId(tmAudit.getId());
            dbHouse.setSubmitAuditTime(LocalDateTime.now());
            dbHouse.setStatus(HouseStatus.WAITING_AUDIT.getCode());
            tmAuditLog.setAuditStatus(AuditStatus.WAITING_AUDIT.getCode());
            if(SysUserRoleEnums.REGION_SHOOT.getRoleKey().equals(tokenMap.getRoleKey())){
                dbHouse.setStatus(HouseStatus.WAITING_REGION_AUDIT.getCode());
                tmAuditLog.setAuditStatus(AuditStatus.SHOOT_AUDIT.getCode());
            }
            dbHouse.setUpdateTime(LocalDateTime.now());
            if(!tmHouseService.updateHouse(dbHouse)){
                log.info("更新房源的审批id失败");
                throw new CommonBaseException(ResultCodeEnum.D101 , "更新房源的审批记录失败");
            }
            int ins = tmOperationService.addNewWithTypeAndContent(getContextUserInfo() , "审核管理" , "提交审核/" + dbHouse.getHouseTitle());
            if(ins != 1){
                log.info("插入操作记录失败");
            }

            //增加审核操作记录
            tmAuditLog.setId(SnowFlakeUUidUtils.generaUUid(null , null , "AUL00000"));
            tmAuditLog.setVrId(dbHouse.getId());
            tmAuditLog.setAuditId(tmAudit.getId());
            tmAuditLog.setAuditType(0);
            tmAuditLog.setAuditTime(LocalDateTime.now());
            tmAuditLog.setAuditorId(tokenMap.getId());
            tmAuditLog.setAuditorName(tokenMap.getNickName());
            tmAuditLog.setBelongCompanyId(tokenMap.getDepartmentId());
            tmAuditLog.setBelongCompanyName(tokenMap.getDepartmentName());
            tmAuditLog.setCreateTime(LocalDateTime.now());
            tmAuditLog.setUpdateTime(LocalDateTime.now());
            tmAuditLog.setIsDelete(DeleteStatus.NOT_DELETE.getCode());
            tmAuditLogService.save(tmAuditLog);

            Map<String , Object> map = new HashMap<>();
            map.put("auditId" , tmAudit.getId());
           return Result.success(map);
        }else{
            return Result.failure("提交失败");
        }
    }


    @PostMapping("/dismissAudit")
    @ApiOperation(value = "撤销审核记录-")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = true, dataType = "String"),
    })
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> dismissAudit(@RequestParam String houseId){
        if(StringUtils.isBlank(houseId)){
            return Result.failure("房源ID不能为空");
        }
        TmHouse dbHouse = tmHouseService.getById(houseId);
        if(null == dbHouse || null == dbHouse.getAuditId()){
            return Result.failure("房源不存在或者未提交审核");
        }
        if(HouseStatus.WAITING_AUDIT.getCode().compareTo(dbHouse.getStatus()) != 0 &&
                HouseStatus.WAITING_REGION_AUDIT.getCode().compareTo(dbHouse.getStatus()) != 0){
            return Result.failure("房源状态非待审核");
        }
        dbHouse = null;
        //抢房源的锁，去掉原来审核的
        dbHouse = tmHouseService.selectForUpdate(houseId);
        if(null == dbHouse){
            return Result.failure("房源抢锁失败，无法撤销审核");
        }
        //走到这里，说明房源的锁已经抢到了
        TmAudit tmAudit = tmAuditService.getById(dbHouse.getAuditId());
        if(null == tmAudit){
            return Result.failure("该房源未提交审核");
        }
        if(null != tmAudit.getAuditStatus() && AuditStatus.AUDITED.getCode().compareTo(tmAudit.getAuditStatus()) == 0){
            return Result.failure("该房源已经审核过，无法撤回");
        }

        ContextTokenBean tokenMap =  getContextUserInfo();
        if(!tokenMap.getId().equals(tmAudit.getCreatorId())){
            return Result.failure("仅支持撤回本人提交的VR项目");
        }
        //开启事务，抢审批记录的锁
        tmAudit = null;
        tmAudit = tmAuditService.selectForUpdate(dbHouse.getAuditId());
        if(null == tmAudit){
            //抢锁失败，则快速返回，释放
            return Result.failure("该房源正在审核，无法撤销");
        }
        //走到这里，说明审核的锁已经抢到了
        //两个锁都抢到了，则可以开始做撤销动作了
        dbHouse.setAuditId("");
        dbHouse.setAuditorId("");
        dbHouse.setAuditorName("");
        dbHouse.setAuditTime(null);
        dbHouse.setStatus(HouseStatus.DRAFT.getCode());
        if(!tmHouseService.updateHouse(dbHouse)){
            throw new CommonBaseException(ResultCodeEnum.D101 , "撤销房源的审批记录失败");
        }

        int deleteAudit = tmAuditService.deleteAudit(tmAudit.getId());
        if(deleteAudit != 1){
            throw new CommonBaseException(ResultCodeEnum.D101 , "删除审批记录失败");
        }

        int ins = tmOperationService.addNewWithTypeAndContent(getContextUserInfo() , "审核管理" , "撤销审核/" + dbHouse.getHouseTitle());
        if(ins != 1){
            log.info("插入操作记录失败");
        }

        return Result.success("撤销成功");
    }


    @GetMapping("/listEstate")
    @ApiOperation("拉取所有楼盘")
    public ViewResult<List<String>> getHouseList() {
        List<String> estates = tmEstateService.list(new LambdaQueryWrapper<TmEstate>().eq(TmEstate::getIsDelete, 0))
                .stream().map(TmEstate::getFcbEstateId).collect(Collectors.toList());
        return ViewResult.success(estates);

    }

}
