package fcb.project.manager.core.controller;

import com.alibaba.fastjson.JSON;
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.service.custom.PanoService;
import fcb.project.manager.base.service.impl.TmAuditLogServiceImpl;
import fcb.project.manager.base.service.impl.TmAuditServiceImpl;
import fcb.project.manager.base.service.impl.TmHouseServiceImpl;
import fcb.project.manager.base.service.impl.TmOperationServiceImpl;
import fcb.project.manager.base.utils.DataUtils;
import fcb.project.manager.core.feignInterfaces.PanoFeign;
import fcb.project.manager.core.feignInterfaces.SceneFeign;
import fdage.back.sdk.base.entity.Result;
import fdage.back.sdk.base.enums.ResultCodeEnum;
import fdage.back.sdk.base.exception.CommonBaseException;
import fdage.back.sdk.base.uuid.SnowFlakeUUidUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 2 * @Author: Abner
 * 3 * @Date: 2021/1/8 11:19
 * 4
 */
@Api(tags = "审核相关接口")
@RestController
@RequestMapping("fcb/project/audit")
@Log4j2
public class AuditController extends BaseController{


    @Autowired
    private TmAuditServiceImpl tmAuditService;

    @Autowired
    private TmAuditLogServiceImpl tmAuditLogService;

    @Autowired
    private TmHouseServiceImpl tmHouseService;

    @Autowired
    private SceneFeign sceneFeign;

    @Autowired
    private PanoService panoService;

    @Autowired
    private TmOperationServiceImpl tmOperationService;

    @GetMapping("/queryOrSearchList")
    @ApiOperation(value = "根据条件拉取所有审批记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "vrTitle", value = "vr项目名称", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "vrType", value = "vr项目类型: 1->新房;2->二手房;", paramType = "query", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "belongEstate", value = "所属楼盘", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "belongCompany", value = "所属公司ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "auditStatus", value = "审核状态: 0->待审核;1->已审核;-1->不通过", paramType = "query", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", paramType = "query", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "query", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = false, dataType = "String")
    })
    public Result<Object> queryList(String vrTitle , Integer vrType,
                                    String belongEstate , String belongCompany,
                                    Integer auditStatus , Long pageNum , Long pageSize , String houseId){

        IPage<TmAudit> resultPage = tmAuditService.queryOrSearchList(vrTitle , vrType ,
                belongEstate , belongCompany ,
                auditStatus , pageNum , pageSize , houseId);
        return  Result.success(DataUtils.assembleResult(resultPage.getTotal(), resultPage.getPages(),
                resultPage.getCurrent(), resultPage.getRecords()));
    }

    @GetMapping("/queryAuditLogList")
    @ApiOperation(value = "根据条件拉取所有审批记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页码", paramType = "query", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "query", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "houseId", value = "房源ID", paramType = "query", required = false, dataType = "String")
    })
    public Result<Object> queryAuditLogList(Long pageNum , Long pageSize , String houseId){

        IPage<TmAuditLog> resultPage = tmAuditLogService.queryAuditLogList(pageNum , pageSize , houseId);
        return  Result.success(DataUtils.assembleResult(resultPage.getTotal(), resultPage.getPages(),
                resultPage.getCurrent(), resultPage.getRecords()));
    }


    @PostMapping("/doAudit")
    @ApiOperation(value = "审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "审核记录ID", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "auditStatus", value = "审核状态: 0->待审核;1->已审核;-1->不通过", paramType = "query", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "auditRemark", value = "审核备注", paramType = "query", required = true, dataType = "String"),
    })
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> audit(@RequestBody AuditRequestBean auditRequestBean , HttpServletRequest request){

        if(null == auditRequestBean){
            return Result.failure("请求体为空");
        }
        if(null == auditRequestBean.getId() || null == auditRequestBean.getAuditStatus()){
            return Result.failure("审核记录ID或者审核结果不能为空");
        }
        if(AuditStatus.AUDITED.getCode().compareTo(auditRequestBean.getAuditStatus()) != 0
                && AuditStatus.REJECT.getCode().compareTo(auditRequestBean.getAuditStatus()) != 0){
            return Result.failure("审核结果非法");
        }
        TmAudit tmAudit = tmAuditService.getById(auditRequestBean.getId());
        if(null == tmAudit){
            return Result.failure("审核记录不存在");
        }

        if(StringUtils.isBlank(tmAudit.getVrId())){
            return Result.failure("该审核记录未绑定房源，无需处理");
        }
        ContextTokenBean tokenMap = getContextUserInfo();

        TmAuditLog tmAuditLog = new TmAuditLog();
        //这里要先锁定当前审核记录
        tmAudit = null;
        tmAudit = tmAuditService.selectForUpdate(auditRequestBean.getId());
        if(null == tmAudit){
            log.info("更新审核状态环节，审核记录[{}]抢锁失败" , auditRequestBean.getId());
            return Result.failure("抢锁失败");
        }
        TmHouse dbHouse = tmHouseService.selectForUpdate(tmAudit.getVrId());
        if(null == dbHouse){
            log.info("更新审核状态环节，审核记录[{}]抢锁失败" , auditRequestBean.getId());
            return Result.failure("抢锁失败");
        }
        if(HouseStatus.AUDITED.getCode().compareTo(dbHouse.getStatus()) == 0 &&
                AuditStatus.AUDITED.getCode().compareTo(tmAudit.getAuditStatus()) == 0){
            return Result.failure("已经审通批过了，无需重复处理");
        }

        String auditResultStr = "";
        Map<String , Object> map = new HashMap<>();
        //若状态为审核通过，判断当前审核状态是拍摄审核，还是地区审核（待审核）
        if(AuditStatus.AUDITED.getCode().compareTo(auditRequestBean.getAuditStatus()) == 0){
            if(AuditStatus.SHOOT_AUDIT.getCode().compareTo(tmAudit.getAuditStatus().intValue()) == 0){
                tmAudit.setAuditStatus(AuditStatus.WAITING_AUDIT.getCode());
                tmAuditLog.setAuditStatus(AuditStatus.REGION_AUDITED.getCode());
                //地区审核通过，修改成待集团审核
                dbHouse.setStatus(HouseStatus.WAITING_AUDIT.getCode());

            }else {
                tmAudit.setAuditStatus(AuditStatus.AUDITED.getCode());
                tmAuditLog.setAuditStatus(AuditStatus.AUDITED.getCode());

                dbHouse.setStatus(HouseStatus.AUDITED.getCode());

                auditResultStr = "审核通过";

                dbHouse.setOnline(1);
                //1、通知看看，翻转场景码的状态
                List<String> sceneNumList = panoService.getKanKanSceneNums(dbHouse.getId() , getToken());
                log.info("720返回的房源的[{}]对应的四维场景码列表为:{}" , dbHouse.getSceneNum() , JSON.toJSONString(sceneNumList));
                if(!CollectionUtils.isEmpty(sceneNumList)){
                    //上线
                    map.put("status" , 1);
                    map.put("sceneNum" , sceneNumList.stream().collect(Collectors.joining(";")));
                    log.info("上送四维看看的参数为:{}" , JSON.toJSONString(map));
                    SceneRspBean rsp = sceneFeign.updateSceneStatus(map , getToken());
                    log.info("四维看看翻转状态返回为:{}" , JSON.toJSONString(rsp));
                    if(null == rsp || rsp.getCode() != 0){
                        log.info("调用看看的更新场景[{}]状态微服务失败" , JSON.toJSONString(sceneNumList));
                        if(null != rsp){
                            log.info("code = {} , msg = {}" , rsp.getCode() , rsp.getMsg());
                        }
                        throw new CommonBaseException(ResultCodeEnum.D101 , "更新看看场景状态失败");
                    }

                }
                //2、通知720，翻转场景码的状态
                panoService.noticeVrAuditStatus(dbHouse.getId() , getToken() , 4);
            }
        }
        if(auditRequestBean.getAuditStatus().compareTo(AuditStatus.REJECT.getCode()) == 0){
            if(AuditStatus.SHOOT_AUDIT.getCode().compareTo(tmAudit.getAuditStatus().intValue()) == 0){
                //处于拍摄审核状态时，修改成地区审核不通过
                tmAudit.setAuditStatus(AuditStatus.REGION_REJECT.getCode());
                tmAuditLog.setAuditStatus(AuditStatus.REGION_REJECT.getCode());
                //地区审核通过，修改成待集团审核
                dbHouse.setStatus(HouseStatus.REGION_REJECT.getCode());
            }else {
                //修改成集团审核不通过
                tmAudit.setAuditStatus(AuditStatus.REJECT.getCode());
                tmAuditLog.setAuditStatus(AuditStatus.REJECT.getCode());

                dbHouse.setStatus(HouseStatus.REJECT.getCode());

                auditResultStr = "审核不通过";
            }
        }

        tmAudit.setAuditRemark(auditRequestBean.getAuditRemark());
        tmAudit.setAuditTime(LocalDateTime.now());
        tmAudit.setAuditorId(tokenMap.getId());
        tmAudit.setAuditorName(tokenMap.getNickName());
        int update = tmAuditService.updateAudit(tmAudit);
        if(update != 1){
            throw new CommonBaseException(ResultCodeEnum.D101 , "更新审核记录失败");
        }

        dbHouse.setAuditId(tmAudit.getId());
        dbHouse.setAuditTime(LocalDateTime.now());
        if(null != tokenMap){
            dbHouse.setAuditorName(tokenMap.getNickName());
            dbHouse.setAuditorId(tokenMap.getId());
        }

        if(!tmHouseService.updateHouse(dbHouse)){
            throw new CommonBaseException(ResultCodeEnum.D101 , "更新房源记录失败");
        }

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

        //增加审核操作记录
        tmAuditLog.setId(SnowFlakeUUidUtils.generaUUid(null , null , "AUL00000"));
        tmAuditLog.setVrId(dbHouse.getId());
        tmAuditLog.setAuditId(tmAudit.getId());
        tmAuditLog.setAuditType(1);
        tmAuditLog.setAuditRemark(auditRequestBean.getAuditRemark());
        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> resMap = new HashMap<>();
        resMap.put("auditId" , tmAudit.getId());
        return Result.success("审核成功" , resMap);
    }

    @PostMapping("/online")
    @ApiOperation(value = "上线/下线")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源ID", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "online", value = "是否上线：1->上线;-0->下线", paramType = "query", required = false, dataType = "Integer"),
    })
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> online(String id , Integer online){

        if(StringUtils.isBlank(id) || null == online){
            return Result.failure("房源ID或者状态不能为空");
        }
        if(online.compareTo(1) != 0 &&
                online.compareTo(0) != 0){
            return Result.failure("上下线状态非法");
        }
        TmHouse tmHouse = tmHouseService.getById(id);
        if(null == tmHouse){
            return Result.failure("房源不存在在");
        }
        tmHouse.setOnline(online);
        if(online.compareTo(0) == 0){
            tmHouse.setStatus(HouseStatus.DRAFT.getCode());
        }
        tmHouseService.updateHouse(tmHouse);
        Map<String , Object> map = new HashMap<>();
        map.put("sceneNum" , tmHouse.getSceneNum());
        if(online.compareTo(1) == 0){
            //上线

        }else{
            //下线
            List<String> sceneNumList = panoService.getKanKanSceneNums(tmHouse.getId() , getToken());
            log.info("720返回的房源的[{}]对应的四维场景码列表为:{}" , tmHouse.getSceneNum() , JSON.toJSONString(sceneNumList));
            if(!CollectionUtils.isEmpty(sceneNumList)){
                map.put("status" , 2);
                map.put("sceneNum" , sceneNumList.stream().collect(Collectors.joining(";")));
                log.info("上送四维看看的参数为:{}" , JSON.toJSONString(map));
                SceneRspBean rsp = sceneFeign.updateSceneStatus(map , getToken());
                log.info("四维看看翻转状态返回为:{}" , JSON.toJSONString(rsp));
                if(null == rsp || rsp.getCode() != 0){
                    log.info("调用看看的更新场景状态微服务失败");
                    if(null != rsp){
                        log.info("code = {} , msg = {}" , rsp.getCode() , rsp.getMsg());
                    }
                    throw new CommonBaseException(ResultCodeEnum.D101 , "更新看看场景状态失败");
                }

            }
            //通知720,告知房源下线(审核通过/上线:4， 下线：3)
            panoService.noticeVrAuditStatus(tmHouse.getId() , getToken() , 3);

            int ins = tmOperationService.addNewWithTypeAndContent(getContextUserInfo() , "审核管理" , "审核管理/审核下线/" + tmHouse.getHouseTitle());
            if(ins != 1){
                log.info("插入操作记录失败");
            }
        }
        return Result.success();
    }


}
