package com.sptg.gateway.controller.estate;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.plugins.Page;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.SysLogConstant;
import com.sptg.common.core.util.WebUtils;
import com.sptg.common.security.annotation.Security;
import com.sptg.common.security.enums.DataFormatEnum;
import com.sptg.common.security.service.SecurityServiceInterface;
import com.sptg.estate.api.constant.EstateSecurityToken;
import com.sptg.estate.api.dto.BuildingDto;
import com.sptg.estate.api.dto.ResidentialDto;
import com.sptg.estate.api.dto.RoomDto;
import com.sptg.estate.api.entity.*;
import com.sptg.estate.api.feigns.*;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.feigns.OrgFeign;
import com.sptg.statistics.api.constant.SysLogMenuConstant;
import com.sptg.statistics.api.entity.SysOperationLog;
import com.sptg.statistics.api.feigns.SysOperationLogFeign;
import com.sptg.third.api.feigns.grid.GridEstateFeign;
import com.sptg.third.api.feigns.qinlin.QLinAuthFeign;
import lombok.RequiredArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * title: RoomController
 * package: com.sptg.gateway.controller.estate
 * description: 房间 网关控制器
 *
 *             
 *                 
 */
@RestController
@RequestMapping("/estate/room")
@RequiredArgsConstructor
public class RoomController {

    private final RoomFeign roomFeign;
    private final UnitFeign unitFeign;
    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final OrgFeign orgFeign;
    private final ResidentialFeign residentialFeign;
    private final SysOperationLogFeign sysOperationLogFeign;
    private final GridEstateFeign gridEstateFeign;
    private final FloorFeign floorFeign;
    private final BuildingFeign buildingFeign;
    private final QLinAuthFeign qLinAuthFeign;

    /**
     * 功能描述:房间页面初始化
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping("/index/{floorId}")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView index(@PathVariable(value = "floorId") Long floorId){
        return new ModelAndView("estate/room-manage").addObject("floorId", floorId);
    }

    /**
     * 功能描述: 管理页面初始化
     * @param id 必填
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/detail/{id}")
    @Security(token = EstateSecurityToken.ESTATE_RESIDENTIAL_UPDATE,format = DataFormatEnum.VIEW)
    public ModelAndView detail(@PathVariable(value = "id")Long id){
        Room room =  this.roomFeign.findRoomById(id);
        if (null == room){
            //  没有找到要的单元
            return new ModelAndView("common/404");
        }
        ModelAndView  modelAndView = new ModelAndView("estate/room-detail");
        modelAndView.addObject("room",room);
        return modelAndView;
    }

    /**
     * 功能描述:房间列表查询
     * @param roomDto 房间业务对象（含查询条件）
     * @param page 分页条件
     * @return ResultBean<Page<Room>>
     *             
     *                       
     */
    @GetMapping(value = "/showRoomList")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_MANAGE,format = DataFormatEnum.JSON)
    public ResultBean<Page<Room>> showRoomList(RoomDto roomDto, Page<Room> page) {
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
        //根据树形选择加载数据；如果没有选中ID，则根据当前账号查询
        if(null == roomDto.getSelectTreeId() || null == roomDto.getSelectTreeType()){
//            roomDto.setOrgPosition(onLineUser.getOrgPosition());
            if (userOrg.getOrgType() == OperationConstant.THREE){//物业机构
                roomDto.setEstatePosition(onLineUser.getOrgPosition());
            }else{
                roomDto.setOrgPosition(onLineUser.getOrgPosition());
            }
        }else{
            //1 机构 2 小区 3社区机构
            if(roomDto.getSelectTreeType() <= OperationConstant.THREE){
                Organization organization = this.orgFeign.getOrgById(roomDto.getSelectTreeId());
                if (roomDto.getSelectTreeType() == OperationConstant.ONE && organization.getOrgType() == OperationConstant.THREE){
                    //机构&物业
                    roomDto.setEstatePosition(organization.getPosition());
                }else if (roomDto.getSelectTreeType() == OperationConstant.TWO && userOrg.getOrgType() == OperationConstant.THREE){
					//小区&用户是物业->则要获取小区的物业estatePosition作为查询条件
                    roomDto.setEstatePosition(this.residentialFeign.findResidentialById(organization.getId()).getEstatePosition());
                }else{
                    roomDto.setOrgPosition(organization.getPosition());
                }
            }
            //4 单元
            if(roomDto.getSelectTreeType() == OperationConstant.FOUR){
                if (userOrg.getOrgType() == OperationConstant.THREE){//物业
                    roomDto.setEstatePosition(this.unitFeign.findUnitById(roomDto.getSelectTreeId()).getEstatePosition());
                }else{//机构
                    roomDto.setOrgPosition(this.unitFeign.findUnitById(roomDto.getSelectTreeId()).getOrgPosition());
                }
            }
        }
        roomDto.setPage(page);
        return this.roomFeign.showRoomList(roomDto);
    }

    /**
     * 功能描述:根据id获取房间
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/findRoomById/{id}")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_MANAGE,format = DataFormatEnum.JSON)
    public ResultBean<Room> findRoomById(@PathVariable(value = "id") Long id){
        Room room = this.roomFeign.findRoomById(id);
        Assert.notNull(room,"房间不存在");
        return new ResultBean<>(ResultEnum.SUCCESS,room);
    }

    /**
     * 功能描述:新增页面初始化
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping(value = "/add")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView add(String selectTreeId){
        ModelAndView modelAndView = new ModelAndView("estate/room-add");
        modelAndView.addObject("selectTreeId",selectTreeId);
        return modelAndView;
    }

    /**
     * 功能描述:新增页面初始化
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/add/{parentId}/{flag}")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView add(@PathVariable(value = "parentId")Long parentId,@PathVariable(value = "flag") Integer flag){
        ModelAndView modelAndView = new ModelAndView("estate/room-add");
        modelAndView.addObject("parentId",parentId);
        modelAndView.addObject("flag",flag);
        return modelAndView;
    }

    /**
     * 功能描述:新增房间
     * @param roomDto 房间业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/addRoom")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_ADD,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> addRoom(RoomDto roomDto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        roomDto.setCreateAccountId(onLineUser.getId());
        ResultBean<Room> resultBean=this.roomFeign.addRoom(roomDto);
        if(null != resultBean.getData() && resultBean.getData().getId()!= null){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            Room room = resultBean.getData();
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_ROOM_MANAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(),roomDto,onLineUser,roomDto);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/

            /*---------------------------------------------------推送房间到网格--------------------------------------------------------*/
            ResultBean<String> stringResultBean = this.gridEstateFeign.gridRoomPush(room);
            if(stringResultBean.getData() != null &&stringResultBean.getData().equals("操作成功")){
                SysOperationLog sysOperationLog1=new SysOperationLog("推送房间数据到网格成功", SysLogConstant.ADD_EVENT,
                        WebUtils.getIp(),room,onLineUser,room);
                sysOperationLogFeign.info(sysOperationLog1);
            }else{
                SysOperationLog sysOperationLog1=new SysOperationLog("推送房间数据到网格失败", SysLogConstant.ADD_EVENT,
                        WebUtils.getIp(),room,onLineUser,room);
                sysOperationLogFeign.info(sysOperationLog1);
            }
            return new ResultBean<>(ResultEnum.SUCCESS);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    /**
     * 功能描述: 编辑页面初始化
     * @param id 必填
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping(value = "/edit/{id}")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_UPDATE,format = DataFormatEnum.VIEW)
    public ModelAndView edit(@PathVariable(value = "id")Long id){
        Room room =  this.roomFeign.findRoomById(id);
        if (null == room){
            //  没有找到要修改的房间
            return new ModelAndView("commom/404");
        }
        ModelAndView  modelAndView = new ModelAndView("estate/room-edit");
        modelAndView.addObject("room",room);
        return modelAndView;
    }

    /**
     * 功能描述:编辑房间
     * @param roomDto 房间业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/updateRoom")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_UPDATE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> updateRoom(RoomDto roomDto){
        if ( null == roomDto || null == roomDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        Room oldObj = this.roomFeign.findRoomById(roomDto.getId());
        ResultBean<Boolean> resultBean=this.roomFeign.updateRoom(roomDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            Room newObj = this.roomFeign.findRoomById(roomDto.getId());
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_ROOM_MANAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),roomDto,onLineUser,oldObj,newObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:删除房间
     * @param roomDto 房间业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/deleteRoom")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteRoom(RoomDto roomDto){
        if ( null == roomDto || null == roomDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        Room oldObj = this.roomFeign.findRoomById(roomDto.getId());
        roomDto.setStatus(OperationConstant.MINUS_ONE);
        ResultBean<Boolean> resultBean=this.roomFeign.deleteRoom(roomDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_ROOM_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),roomDto,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }
    
    /**
     * 功能描述:批量删除房间
     * @param ids 选中的id集合
     * @return ResultBean<Boolean>
     *             
     *                      
     */
    @PostMapping(value = "/deleteRoomList")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteRoomList(@RequestBody List<String> ids){
        if (null == ids || ids.size() <=0){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        RoomDto roomDto = new RoomDto();
        roomDto.setIds(ids);
        ResultBean<Boolean> resultBean = this.roomFeign.deleteRoomList(roomDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_ROOM_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),roomDto,onLineUser);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }
    
    /**
     * 功能描述:导入房间
     * @param flag 3 房间
     * @return ModelAndView
     *             
     *                      
     */
    @RequestMapping(value = "/indexImportExcel/{flag}")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_IMPORT,format = DataFormatEnum.VIEW)
    public ModelAndView indexImportExcel(@PathVariable(value = "flag")String flag) {
        ModelAndView modelAndView = new ModelAndView("common/import-excel");
        modelAndView.addObject("flag",flag);
        return modelAndView;
    }

    /**
     * 功能描述:导出房间
     * @param response
     *             
     *                      
     */
    @RequestMapping(value = "/exportRoom")
    @Security(token = EstateSecurityToken.ESTATE_ROOM_EXPORT)
    public void exportRoom(HttpServletResponse response) {
        try {
            response.sendRedirect("/common/excel/exportExcel/3");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /* -------------------------------------------------- 公共方法,不做权限限制 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------------------- */

    /**
     * 功能描述:根据父节点查找房间
     * @param roomDto 房间业务对象
     * @return ResultBean<Room>
     *             
     *                       
     */
    @GetMapping(value = "/findListByPid")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<Room> findListByPid(RoomDto roomDto){
        if ( null == roomDto || null == roomDto.getUnitId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        return this.roomFeign.getByUnitId(roomDto.getUnitId());
    }

    /**
     * 功能描述:根据位置查询的所有房间
     * @param roomDto 房间业务对象
     * @return ResultBean<Residential>
     *             
     *                      
     */
    @GetMapping(value = "/findListByPosition")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<Room> findListByPosition(RoomDto roomDto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
        if(null == roomDto.getUnitId()){
            if (userOrg.getOrgType() == OperationConstant.THREE){
                //物业
                roomDto.setEstatePosition(onLineUser.getOrgPosition());
            }else{
                //机构
                roomDto.setOrgPosition(onLineUser.getOrgPosition());
            }
        }else{
            Unit unit = this.unitFeign.findUnitById(roomDto.getUnitId());
            if (userOrg.getOrgType() == OperationConstant.THREE){
                //物业
                roomDto.setEstatePosition(unit.getEstatePosition());
            }else{
                //机构
                roomDto.setOrgPosition(unit.getOrgPosition());
            }
        }
        return this.roomFeign.findListByPosition(roomDto);
    }

    /**
     * 功能描述: 根据名称模糊查询
     * @param dto
     * @return ResultBean<Room>
     *
     */
    @GetMapping(value = "/getListByLikeName")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<Room> getListByLikeName(RoomDto dto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
        if(null == dto.getSelectTreeId()) {
            if (userOrg.getOrgType() == OperationConstant.THREE){
                dto.setEstatePosition(onLineUser.getOrgPosition());
            }else{
                dto.setOrgPosition(onLineUser.getOrgPosition());
            }
        }else{
            Organization organization = this.orgFeign.getOrgById(dto.getSelectTreeId());
            if (organization.getOrgType() == OperationConstant.THREE){
                dto.setEstatePosition(organization.getPosition());
            }else{
                dto.setOrgPosition(organization.getPosition());
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,this.roomFeign.getListByLikeName(dto));
    }


    /**
     * 同步亲邻房间数据
     *
     * @param residentialId
     * @return
     */
    @PostMapping(value = "/syncRoom/{id}")
    @Security(token = "estate:residential:sync")
    public ResultBean sync(@PathVariable(value = "id") Long residentialId) {

        Residential residential = this.residentialFeign.findResidentialById(residentialId);
        if (null == residential) {
            return new ResultBean(ResultEnum.FAILURE);
        }
        BuildingDto buildingDto = new BuildingDto();
        buildingDto.setResidentialId(residentialId);
        List<Floor> floorList = this.floorFeign.getListByXqId(residentialId);
        this.syncRoom(residential,floorList);
        return new ResultBean(ResultEnum.SUCCESS);
    }

    private void syncRoom(Residential residential,List<Floor> floorList) {
        int addResult = 0;
        int updateResult = 0;

        for (int j = 0; j < floorList.size(); j++) {
            //当前楼层
            Floor floor = floorList.get(j);
            //当前单元
            Unit unit = this.unitFeign.findUnitById(floor.getUnitId());
            //当前楼栋
            Building building = this.buildingFeign.findBuildingById(floor.getBuildingId());


            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
            headers.add(HttpHeaders.HOST, "qiotapi.qinlinkeji.com");
            headers.add("Cookie", "acw_tc=2760821216040233709218017edfed503c3f299563c0716431831777dc716e");
            Map<String, Object> map = new HashMap<>();

            map.put("communityId", residential.getOldId());
            map.put("id", floor.getOldId());
            map.put("nodeType", 3);
            map.put("pageNum", 1);
            map.put("pageSize", 100000);

            HttpEntity<String> requestEntity = new HttpEntity<String>(JSONUtil.toJsonStr(map), headers);
            ParameterizedTypeReference<Object> reference = new ParameterizedTypeReference<Object>() {
            };
            String sessionId = this.qLinAuthFeign.qLinAuth();
            String url = "https://qiotapi.qinlinkeji.com/admin/building/house/findUserByCondition?sessionId="+sessionId;
            URI uri = URI.create(url);
            responseEntity = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);


            Map map1 = (Map) responseEntity.getBody();
            Map map2 = (Map) map1.get("data");
            List<Map> list = (List<Map>) map2.get("list");
            for (int i = 0; i < list.size(); i++) {
                Room room = new Room();
                room.setOldId(list.get(i).get("houseId").toString());
                room.setName((String)list.get(i).get("houseName"));
                room.setFloorId(floor.getId());
                room.setFloorName(floor.getName());
                room.setUnitId(floor.getUnitId());
                room.setUnitName(floor.getUnitName());
                room.setBuildingId(floor.getBuildingId());
                room.setBuildingName(floor.getBuildingName());
                room.setResidentialId(floor.getResidentialId());
                room.setResidentialName(floor.getResidentialName());

                Room room1 = this.roomFeign.getByOldId(room.getOldId());
                if(room1 != null){
                    room.setId(room1.getId());
                    boolean result1 = this.roomFeign.updateEntity(room);
                    if(result1){
                        updateResult = updateResult + 1;
                    }

                }else{
                    int result1 = this.roomFeign.addRoomSync(room);
                    if(result1>0){
                        //楼层房间数加1
                        floor.setRoomNumber(floor.getRoomNumber()+1);
                        this.floorFeign.updateEntity(floor);
                        //单元房间数加1
                        unit.setRoomNumber(unit.getRoomNumber()+1);
                        this.unitFeign.updateEntity(unit);
                        //楼栋房间数加1
                        building.setRoomNumber(building.getRoomNumber()+1);
                        this.buildingFeign.updateEntity(building);
                        //社区房间数加1
                        residential.setRoomNumber(residential.getRoomNumber()+1);
                        this.residentialFeign.updateResidentialEntity(residential);
                    }
                    addResult = addResult + result1;
                }

            }
            System.out.println("楼层id为"+floor.getOldId()+"的房间列表："+list);
        }
        System.out.println("addResult"+addResult+" "+"update"+updateResult);
    }
}
