package com.sptg.estate.biz.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.sptg.common.core.beans.ExcelResultEnum;
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.SymbolConstant;
import com.sptg.common.core.util.CommonUtil;
import com.sptg.estate.api.dto.BuildingDto;
import com.sptg.estate.api.entity.Residential;
import com.sptg.estate.api.entity.Building;
import com.sptg.estate.api.entity.Unit;
import com.sptg.estate.api.enums.EstateEnum;
import com.sptg.estate.biz.mapper.BuildingMapper;
import com.sptg.estate.biz.service.AccessCardServiceInterface;
import com.sptg.estate.biz.service.ResidentialServiceInterface;
import com.sptg.estate.biz.service.BuildingServiceInterface;
import com.sptg.estate.biz.service.UnitServiceInterface;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * title: BuildingServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 楼栋 服务层实现层
 */
@Service
@RequiredArgsConstructor
public class BuildingServiceImpl extends ServiceImpl<BuildingMapper, Building> implements BuildingServiceInterface {

    private final UnitServiceInterface unitServiceInterface;
    private final ResidentialServiceInterface residentialServiceInterface;
    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    @Lazy
    private AccessCardServiceInterface accessCardServiceInterface;

    private final static String IMPORT_CACHE_ROOM_CODE_NAME = "sptg:import:building:code:name";
    private final static String IMPORT_CACHE_ROOM_CODE = "sptg:import:card:building:code";


    @Override
    public ResultBean<Page<Building>> showBuildingList(BuildingDto buildingDto) {
        // 构建查询条件
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
//        if (buildingDto.getStatus() != null) {
//            wrapper.eq("i_status", buildingDto.getStatus());
//        } else {
            wrapper.eq("i_status", OperationConstant.ZERO);
//        }
        //根据旧平台id获取
        if (buildingDto.getResidentialId() != null) {
            wrapper.eq("l_residential_id", buildingDto.getResidentialId());
        }

        if(buildingDto.getOrgPosition() != null){
            wrapper.like("s_org_position",buildingDto.getOrgPosition(),SqlLike.RIGHT);
        }
        if(buildingDto.getName() != null){
            wrapper.like("s_name",buildingDto.getName(),SqlLike.DEFAULT);
        }
        wrapper.orderBy("d_create_time",false);

        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(buildingDto.getPage(), wrapper));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Building> addBuilding(BuildingDto buildingDto) {

        Residential residential = this.residentialServiceInterface.findResidentialById(buildingDto.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        if (this.findBuildingByCondition(buildingDto) > 0) {
            return new ResultBean<>(EstateEnum.BUILDING_DATA_EXISTES);
        }
        buildingDto.setResidentialId(residential.getId());
        buildingDto.setResidentialName(residential.getName());

        buildingDto.setCreateDate(new Date());
        buildingDto.setStatus(OperationConstant.ZERO);
        buildingDto.setUnitNumber(0);
        buildingDto.setFloorNumber(0);
        buildingDto.setRoomNumber(0);
//        buildingDto.setId(IdWorker.getId());
//        //************************保存组织路径
        buildingDto.setOrgPosition(residential.getOrgPosition() + buildingDto.getId() + SymbolConstant.BACK_SLASH);
//        //************************保存物业路径
//        buildingDto.setEstatePosition(residential.getEstatePosition() + buildingDto.getId() + SymbolConstant.BACK_SLASH);
//

        if (this.insert(buildingDto)) {
            buildingDto.setOrgPosition(residential.getOrgPosition() + buildingDto.getId() + SymbolConstant.BACK_SLASH);
            this.updateById(buildingDto);
            //小区楼栋数量加+1
            residential.setBuildingNumber(residential.getBuildingNumber() + 1);
            if (this.residentialServiceInterface.updateById(residential)) {
                //通知网格修改小区（待做）
                return new ResultBean<>(ResultEnum.SUCCESS, buildingDto);
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public Building findBuildingById(Long id) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        wrapper.eq("l_id", id);
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        return this.selectOne(wrapper);
    }

    @Override
    public ResultBean<Boolean> updateBuilding(BuildingDto buildingDto) {
//        if (this.findBuildingByCondition(buildingDto) > 0) {
//            return new ResultBean<>(EstateEnum.ROOM_DATA_EXISTES);
//        }
        if (this.updateById(buildingDto)) {
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteBuilding(BuildingDto buildingDto) {
        Building building = this.findBuildingById(buildingDto.getId());
        if (null == building) {
            return new ResultBean<>(ResultEnum.ERROR);
        }

//        Unit unit = this.unitServiceInterface.findUnitById(building.getUnitId());
//        if(null == unit ){
//            return new ResultBean<>(ResultEnum.ERROR);
//        }
        Residential residential = this.residentialServiceInterface.findResidentialById(building.getResidentialId());
        if(null == residential){
            return new ResultBean<>(ResultEnum.ERROR);
        }
//        if(building.getUserNumber() > 0){
//            return new ResultBean<>(EstateEnum.HAVE_CHILDREN);
//        }
        building.setStatus(buildingDto.getStatus());
        if(this.updateById(building)){
            //小区楼栋数量 -1
            residential.setBuildingNumber(residential.getBuildingNumber()-1);
            if(this.residentialServiceInterface.updateById(residential)){
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public ResultBean<Boolean> trashOrRecover(BuildingDto buildingDto) {
        Building building = this.findBuildingById(buildingDto.getId());
//        if(null == building ){
//            return new ResultBean<>(ResultEnum.ERROR);
//        }
//        Unit unit = this.unitServiceInterface.findUnitById(building.getUnitId());
//        if(null == unit ){
//            return new ResultBean<>(ResultEnum.ERROR);
//        }
//        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
//        if(null == residential ){
//            return new ResultBean<>(ResultEnum.ERROR);
//        }
//        building.setStatus(buildingDto.getStatus());
//        if(this.updateById(building)){
//            //删除关联卡及下发的卡号
//            if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(building.getId(),OperationConstant.ONE)){
//                this.deleteCache(building);
//                return new ResultBean<>(ResultEnum.SUCCESS,true);
//            }
//        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteBuildingList(BuildingDto buildingDto) throws Exception {
        List<String> ids = buildingDto.getIds();
        String msg;
//        for(String id : ids){
//            Building building = this.findBuildingById(Long.valueOf(id));
//            if(null == building ){
//                msg = "楼栋不存在，请核实后重新操作";
//                throw new Exception(msg);
//            }
//            Unit unit = this.unitServiceInterface.findUnitById(building.getUnitId());
//            if(null == unit ){
//                msg = building.getName() + "楼栋所属单元不存在，请核实后重新操作";
//                throw new Exception(msg);
//            }
//            Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
//            if(null == residential ){
//                msg = building.getName() + "楼栋所属小区不存在，请核实后重新操作";
//                throw new Exception(msg);
//            }
//            if(building.getUserNumber() > 0){
//                msg = unit.getName()+"楼栋含有下级数据，请核实后重新操作";
//                throw new Exception(msg);
//            }
//            building.setStatus(OperationConstant.MINUS_ONE);
//            if(this.updateById(building)){
//                //小区楼栋数量 -1
//                residential.setBuildingNumber(residential.getBuildingNumber()-1);
//                if(this.residentialServiceInterface.updateById(residential)){
//                    //小区楼栋数量 -1
//                    unit.setBuildingNumber(unit.getBuildingNumber() -1);
//                    if(this.unitServiceInterface.updateById(unit)){
//                        //删除关联卡及下发的卡号
//                        if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(building.getId(),OperationConstant.ONE)){
//                            this.deleteCache(building);
//                        }else{
//                            msg = unit.getName()+"楼栋删除关联卡失败，请核实后重新操作";
//                            throw new Exception(msg);
//                        }
//                    }
//                }
//            }
//        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    public ResultBean<Building> findListByPosition(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
//        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
//        //根据机构
//        if(StringUtils.isNotBlank(buildingDto.getOrgPosition())) {
//            wrapper.like("s_org_position", buildingDto.getOrgPosition(), SqlLike.RIGHT);
//        }
//        //根据物业
//        if(StringUtils.isNotBlank(buildingDto.getEstatePosition())) {
//            wrapper.like("s_estate_position", buildingDto.getEstatePosition(), SqlLike.RIGHT);
//        }
//        if (buildingDto.getResidentialId() != null){
//            wrapper.eq("l_residential_id",buildingDto.getResidentialId());
//        }
//        //名称
//        if(StringUtils.isNotBlank(buildingDto.getName())) {
//            wrapper.like("s_name", buildingDto.getName(),SqlLike.DEFAULT);
//        }
//        if (buildingDto.getIsSelect()){
//            wrapper.last("limit 10");
//        }
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectList(wrapper));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> importBuildingList(BuildingDto buildingDto) {
//        List<Building> list = buildingDto.getList();
//        if(this.insertBatch(list,500)){
//            Map<Long,Integer> residentialMap = buildingDto.getResidentialMap();
//            for (Map.Entry<Long, Integer> entry : residentialMap.entrySet()) {
//                Residential residential = this.residentialServiceInterface.findResidentialById(entry.getKey());
//                residential.setBuildingNumber(residential.getBuildingNumber() + entry.getValue());
//                this.residentialServiceInterface.updateById(residential);
//            }
//            Map<Long,Integer> unitMap = buildingDto.getUnitMap();
//            for (Map.Entry<Long, Integer> entry : unitMap.entrySet()) {
//                Unit unit = this.unitServiceInterface.findUnitById(entry.getKey());
//                unit.setBuildingNumber(unit.getBuildingNumber() + entry.getValue());
//                this.unitServiceInterface.updateById(unit);
//            }
//        }
        return new ResultBean<>(ExcelResultEnum.SUCCESS, true);
    }

    @Override
    public Building findBuildingByNameAndNumber(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
//        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
//        wrapper.eq("l_unit_id",buildingDto.getUnitId());
//        if(StringUtils.isNotBlank(buildingDto.getName())){
//            //名称
//            wrapper.eq("s_name",buildingDto.getName());
//        }
//        if(StringUtils.isNotBlank(buildingDto.getHouseNumber())){
//            //编号
//            wrapper.eq("s_house_number",buildingDto.getHouseNumber());
//        }
        return this.selectOne(wrapper);
    }

    @Override
    public Building addBuildingByImport(Building building) {
//        Unit unit = this.unitServiceInterface.findUnitById(building.getUnitId());
//        if(null == unit ){
//            return null;
//        }
//        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
//        if(null == residential ){
//            return null;
//        }
//        building.setResidentialId(residential.getId());
//        building.setResidentialName(residential.getName());
//        building.setUnitName(unit.getName());
//        building.setUserNumber(OperationConstant.ZERO);
//        building.setRootOrgId(unit.getRootOrgId());
//        building.setCreateDate(new Date());
//        building.setStatus(OperationConstant.ZERO);
//        building.setId(IdWorker.getId());
//        building.setOrgPosition(unit.getOrgPosition() + building.getId() + SymbolConstant.BACK_SLASH);
//        if(this.insert(building)){
//            //小区楼栋数量加+1
//            residential.setBuildingNumber(residential.getBuildingNumber() + 1);
//            if(this.residentialServiceInterface.updateById(residential)){
//                //单元楼栋数量加+1
//                unit.setBuildingNumber(unit.getBuildingNumber() + 1);
//                if(this.unitServiceInterface.updateById(unit)){
//                    return building;
//                }
//            }
//        }
        return null;
    }

    @Override
    public List<Building> getListByLikeName(BuildingDto dto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status", OperationConstant.ZERO);
//        if (dto.getId() != null){
//            wrapper.eq("l_id",dto.getId());
//        }
//        //名称
        if (StringUtils.isNotBlank(dto.getName())){
            wrapper.like("s_name",dto.getName(),SqlLike.DEFAULT);
        }
        if (dto.getResidentialId() != null){
            wrapper.eq("l_residential_id",dto.getResidentialId());
        }
//        if (dto.getUnitId() != null){
//            wrapper.eq("l_unit_id",dto.getUnitId());
//        }
//        if (StringUtils.isNotBlank(dto.getOrgPosition())){
//            wrapper.like("s_org_position",dto.getOrgPosition(), SqlLike.RIGHT);
//        }
//        if (StringUtils.isNotBlank(dto.getEstatePosition())){
//            wrapper.like("s_estate_position",dto.getEstatePosition(),SqlLike.DEFAULT);
//        }
        if (dto.getIsSelect()){
            wrapper.last("limit 10");
        }
        return this.selectList(wrapper);
    }

    @Override
    public Building findByBuildingNumber(String buildingNumber) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //根据单元id
        wrapper.eq("s_building_number", buildingNumber);
        return this.selectOne(wrapper);
    }

    @Override
    public Building findByOldId(String oldId) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //根据单元id
        wrapper.eq("l_old_id", oldId);
        return this.selectOne(wrapper);
    }

    @Override
    public List<Building> getListByCondition(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //名称
        if (StringUtils.isNotBlank(buildingDto.getName())){
            wrapper.eq("s_name", buildingDto.getName());
        }
         //根据orgPosition
        if (StringUtils.isNotBlank(buildingDto.getOrgPosition())){
            wrapper.like("s_org_position", buildingDto.getOrgPosition());
        }
        if(buildingDto.getResidentialId()!=null){
            wrapper.eq("l_residential_id",buildingDto.getResidentialId());
        }
        return this.selectList(wrapper);
    }

    @Override
    public int addBuildingBySync(Building building) {
        if (this.insert(building)) {
            return 1;
        }
        return 0;
    }

    @Override
    public int updateBuildingBySync(Building building) {
        if (this.updateById(building)) {
            return 1;
        }
        return 0;
    }

    @Override
    public ResultBean<Building> getByUnitId(Long unitId) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //根据单元id
        wrapper.eq("l_unit_id", unitId);
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectList(wrapper));
    }

    @Override
    public int getBuildingAccount(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
//        wrapper.like("s_org_position",buildingDto.getOrgPosition(),SqlLike.RIGHT);
        //当月新增
        if (OperationConstant.TWO == buildingDto.getIsAllType()) {
            wrapper.and("DATE_FORMAT(t_create_date,'%Y%m')=DATE_FORMAT(NOW(),'%Y%m')");
        }
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        return this.selectCount(wrapper);
    }

    @Override
    public List<Building> getListByBuildingId(List<Long> buildingIds) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //用户id
        wrapper.in("l_id", buildingIds);
        return this.selectList(wrapper);
    }

    @Override
    public Page<Building> pagingByIds(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //根据ids
        wrapper.in("l_id", buildingDto.getIds());
        return this.selectPage(buildingDto.getPage(), wrapper);
    }

    @Override
    public int findBuildingByCondition(BuildingDto buildingDto) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //过滤自己
        if (null != buildingDto.getId()) {
            wrapper.notIn("l_id", buildingDto.getId());
        }
        return this.baseMapper.findBuildingByCondition(buildingDto, wrapper);
    }

    /* -------------------------------------------------- 内部方法 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------- */

    /**
     * 功能描述:删除缓存
     *
     * @param building
     */
    private void deleteCache(Building building) {
        HashOperations<String, String, String> hashOperations = this.redisTemplate.opsForHash();
        long residentialId = building.getResidentialId();
//        long unitId = building.getUnitId();
//        String buildingName = building.getName();
//        String houseNumber = building.getHouseNumber();
//        StringBuffer sb = new StringBuffer(residentialId+""+unitId + "-"+buildingName+"-"+houseNumber);
//        String hashKey = sb.toString();
//        String json = hashOperations.get(IMPORT_CACHE_ROOM_CODE_NAME,hashKey);
//        if (!StringUtils.isEmpty(json)) {
//            hashOperations.delete(IMPORT_CACHE_ROOM_CODE_NAME,hashKey);
//        }
//        sb = new StringBuffer(unitId+""+houseNumber);
//        hashKey = sb.toString();
//        json = hashOperations.get(IMPORT_CACHE_ROOM_CODE,hashKey);
//        if (!StringUtils.isEmpty(json)) {
//            hashOperations.delete(IMPORT_CACHE_ROOM_CODE,hashKey);
//        }
    }

    private Building findByHouseNumber(Long unitId, String houseNumber) {
        Wrapper<Building> wrapper = new EntityWrapper<>();
        wrapper.eq("l_unit_id", unitId);
        wrapper.eq("s_house_number", houseNumber);
        return this.selectOne(wrapper);
    }

}
