package com.sptg.gateway.controller.estate;

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.*;
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 lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * title: BuildingController
 * package: com.sptg.gateway.controller.estate
 * description: 单元 网关控制器
 *
 *
 *
 */
@RestController
@RequestMapping("/estate/building")
@RequiredArgsConstructor
public class BuildingController {

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

    /**
     * 功能描述:楼栋页面初始化
     * @return ModelAndView
     *
     *
     */
    @GetMapping("/index/{residentialId}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView index(@PathVariable(value = "residentialId")Long residentialId){
        ModelAndView modelAndView = new ModelAndView("estate/building-manage");
        modelAndView.addObject("residentialId", residentialId);
        return modelAndView;
    }

    /**
     * 功能描述:楼栋页面初始化
     * @return ModelAndView
     *
     *
     */
    @GetMapping("/addBatchView/{residentialId}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView addBatchView(@PathVariable(value = "residentialId")Long residentialId){
        ModelAndView modelAndView = new ModelAndView("estate/batch-add");
        modelAndView.addObject("residentialId", residentialId);
        return modelAndView;
    }

    /**
     * 功能描述: 管理页面初始化
     * @param id 必填
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/detail/{id}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_UPDATE,format = DataFormatEnum.VIEW)
    public ModelAndView detail(@PathVariable(value = "id")Long id){
        Building building =  this.buildingFeign.findBuildingById(id);

        if (null == building){
            //  没有找到要的楼栋
            return new ModelAndView("common/404");
        }
        ModelAndView  modelAndView = new ModelAndView("estate/building-detail");
        modelAndView.addObject("building",building);
        return modelAndView;
    }

    /**
     * 功能描述:楼栋列表查询
     * @param buildingDto 楼栋业务对象（含查询条件）
     * @param page 分页条件
     * @return  ResultBean<Page<Unit>>
     *
     *
     */
    @GetMapping(value = "/showBuildingList")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_MANAGE,format = DataFormatEnum.JSON)
    public ResultBean<Page<Building>> showBuildingList(BuildingDto buildingDto, Page<Building> page) {
        //根据树形选择加载数据；如果没有选中ID，则根据当前账号查询
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
//        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
//        if(null == buildingDto.getSelectTreeId() || null == buildingDto.getSelectTreeType()) {
//            if (userOrg.getOrgType() == OperationConstant.THREE){
//                buildingDto.setEstatePosition(onLineUser.getOrgPosition());
//            }else{
//                buildingDto.setOrgPosition(onLineUser.getOrgPosition());
//            }
////            unitDto.setOrgPosition(onLineUser.getOrgPosition());
//        }else{
//            //1 机构 2 小区
//            Organization organization = this.orgFeign.getOrgById(buildingDto.getSelectTreeId());
//            if (organization.getFlag() == OperationConstant.ONE){
//                //机构
//                if (organization.getOrgType() == OperationConstant.THREE){//物业
//                    buildingDto.setEstatePosition(organization.getPosition());
//                }else{
//                    buildingDto.setOrgPosition(organization.getPosition());
//                }
//            }
//            if (organization.getFlag() == OperationConstant.TWO){
//                //小区(则还要判断当前账号的身份)
//                if (userOrg.getOrgType() == OperationConstant.THREE){
//                    //物业账号
//                    buildingDto.setEstatePosition(this.residentialFeign.findResidentialById(organization.getId()).getEstatePosition());
//                }else{
//                    //机构账号
//                    buildingDto.setOrgPosition(organization.getPosition());
//                }
//            }
//        }
        buildingDto.setOrgPosition(onLineUser.getOrgPosition());
        buildingDto.setPage(page);

        return this.buildingFeign.showBuildingList(buildingDto);
    }

    /**
     * 功能描述:根据id获取楼栋
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/findBuildingById/{id}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_MANAGE,format = DataFormatEnum.JSON)
    public ResultBean<Building> findBuildingById(@PathVariable(value = "id") Long id){
        Building building = this.buildingFeign.findBuildingById(id);
        Assert.notNull(building,"楼栋不存在");
        return new ResultBean<>(ResultEnum.SUCCESS,building);
    }

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

    /**
     * 功能描述:新增页面初始化-带参数
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/add/{residentialId}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView add(@PathVariable(value = "residentialId") Long residentialId){
        ModelAndView modelAndView = new ModelAndView("estate/building-add");
        modelAndView.addObject("residentialId",residentialId);
        return modelAndView;
    }

    /**
     * 功能描述:新增楼栋
     * @param buildingDto 楼栋业务对象
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/addBuilding")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_ADD,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> addBuilding(BuildingDto buildingDto){
        ResultBean<Building> bean;
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        buildingDto.setCreateAccountId(onLineUser.getId());
       bean = this.buildingFeign.addBuilding(buildingDto);
        if(null != bean && bean.getData()!=null){

            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_BUILDING_MANAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(),buildingDto,onLineUser,buildingDto);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/

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

    /**
     * 功能描述:新增楼栋
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/addBuildingBatch")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_ADD,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> addBuildingBatch(BuildingBatchAdd batchAdd){

        Account onLineUser = this.securityServiceInterface.getOnLineUser();

        if(this.buildingFeign.addBuildingBatch(batchAdd)){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_BUILDING_MANAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(), batchAdd, onLineUser, batchAdd);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/

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

    /**
     * 功能描述: 编辑页面初始化
     * @param id 必填
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/edit/{id}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_UPDATE,format = DataFormatEnum.VIEW)
    public ModelAndView edit(@PathVariable(value = "id")Long id){
        Building building =  this.buildingFeign.findBuildingById(id);
        if (null == building){
            //  没有找到要修改的楼栋
            return new ModelAndView("common/404");
        }
        ModelAndView  modelAndView = new ModelAndView("estate/building-edit");
        modelAndView.addObject("building",building);
        return modelAndView;
    }

    /**
     * 功能描述:编辑楼栋
     * @param buildingDto 楼栋业务对象
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/updateBuilding")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_UPDATE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> updateBuilding(BuildingDto buildingDto){
        if ( null == buildingDto || null == buildingDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        Building oldObj = this.buildingFeign.findBuildingById(buildingDto.getId());
        ResultBean<Boolean> resultBean=this.buildingFeign.updateBuilding(buildingDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            Building newObj = this.buildingFeign.findBuildingById(buildingDto.getId());
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_BUILDING_MANAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),buildingDto,onLineUser,oldObj,newObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:删除楼栋
     * @param buildingDto 楼栋业务对象
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/deleteBuilding")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteBuilding(BuildingDto buildingDto){
        if ( null == buildingDto || null == buildingDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        Building oldObj = this.buildingFeign.findBuildingById(buildingDto.getId());
        buildingDto.setStatus(OperationConstant.MINUS_ONE);
        buildingDto.setResidentialId(oldObj.getResidentialId());
        ResultBean<Boolean> resultBean=this.buildingFeign.deleteBuilding(buildingDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_BUILDING_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),buildingDto,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:批量删除楼栋
     * @param ids 选中id集合
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/deleteBuildingList")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteBuildingList(@RequestBody List<String> ids){
        if (null == ids || ids.size() <=0){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        BuildingDto buildingDto = new BuildingDto();
        buildingDto.setIds(ids);
        ResultBean<Boolean> resultBean = this.buildingFeign.deleteBuildingList(buildingDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_BUILDING_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),buildingDto,onLineUser);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:导入楼栋
     * @param flag 7 楼栋
     * @return ModelAndView
     *
     *
     */
    @RequestMapping(value = "/indexImportExcel/{flag}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_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 = "/exportBuilding")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_EXPORT)
    public void exportBuilding(HttpServletResponse response) {
        try {
            response.sendRedirect("/common/excel/exportExcel/7");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/clearUnit/{buildingId}")
    @Security(token = EstateSecurityToken.ESTATE_BUILDING_DELETE)
    public ResultBean clearUnit(@PathVariable("buildingId") Long buildingId) {
        Building building = buildingFeign.findBuildingById(buildingId);
        Long residentialId = building.getResidentialId();
        boolean b = false;

        //进行删除房屋信息处理
        RoomDto roomDto = new RoomDto();
        roomDto.setBuildingId(buildingId);
        List<Room> rooms = roomFeign.getListByCondition(roomDto);
        if (rooms.size() > 0) {
            List<Room> roomList = new ArrayList<>();
            rooms.forEach(room -> {
                Room room1 = new Room();
                BeanUtils.copyProperties(room, room1);
                room1.setStatus(OperationConstant.MINUS_ONE);
                roomList.add(room1);
            });
            b = roomFeign.updateRoomList(roomList);
        }

        //进行删除楼层信息处理
        FloorDto floorDto = new FloorDto();
        floorDto.setBuildingId(buildingId);
        List<Floor> floors = floorFeign.getListByCondition(floorDto);
        if (floors.size() > 0) {
            List<Floor> floorList = new ArrayList<>();
            floors.forEach(floor -> {
                Floor floor1 = new Floor();
                BeanUtils.copyProperties(floor, floor1);
                floor1.setStatus(OperationConstant.MINUS_ONE);
                floorList.add(floor1);
            });
            b = floorFeign.updateFloorList(floorList);
        }

        //进行删除单元信息处理
        UnitDto unitDto = new UnitDto();
        unitDto.setBuildingId(buildingId);
        List<Unit> units = unitFeign.getListByCondition(unitDto);
        if (units.size() > 0) {
            List<Unit> unitList = new ArrayList<>();
            units.forEach(unit -> {
                Unit unit1 = new Unit();
                BeanUtils.copyProperties(unit, unit1);
                unit1.setStatus(OperationConstant.MINUS_ONE);
                unitList.add(unit1);
            });
            b = unitFeign.updateUnitList(unitList);
            if (b) {
                Building building1 = new Building();
                building1.setId(buildingId);
                building1.setUnitNumber(0);
                building1.setFloorNumber(0);
                building1.setRoomNumber(0);
                buildingFeign.updateEntity(building1);

                Residential residential = residentialFeign.findResidentialById(residentialId);
                Integer unitNumber = residential.getUnitNumber() - units.size();
                residential.setUnitNumber(unitNumber);
                Integer floorNumber = residential.getFloorNumber() - floors.size();
                residential.setFloorNumber(floorNumber);
                Integer roomNumber = residential.getRoomNumber() - rooms.size();
                residential.setRoomNumber(roomNumber);
                residentialFeign.updateEntity(residential);
            }
        }
        return new ResultBean(ResultEnum.SUCCESS, b);
    }

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





    /**
     * 功能描述: 根据小区Id查询楼栋列表
     * @param residentialId 小区Id
     * @return ResultBean<Unit>
     *
     *
     */
    @GetMapping(value = "/getListByResidentialId/{residentialId}")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<Building> getListByResidentialId(@PathVariable(value = "residentialId") Long residentialId){
        BuildingDto buildingDto = new BuildingDto();
        buildingDto.setResidentialId(residentialId);
        List<Building> buildingList = this.buildingFeign.getListByCondition(buildingDto);
        return new ResultBean<>(ResultEnum.SUCCESS,buildingList);
    }

    /**
     * 功能描述: 根据名称模糊查询
     * @param dto
     * @return ResultBean<Unit>
     *
     */
    @GetMapping(value = "/getListByLikeName")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<Building> getListByLikeName(BuildingDto 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.buildingFeign.getListByLikeName(dto));
    }
}
