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.estate.api.dto.FloorDto;
import com.sptg.estate.api.entity.Building;
import com.sptg.estate.api.entity.Residential;
import com.sptg.estate.api.entity.Floor;
import com.sptg.estate.api.entity.Unit;
import com.sptg.estate.api.enums.EstateEnum;
import com.sptg.estate.biz.mapper.FloorMapper;
import com.sptg.estate.biz.service.*;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.feigns.OrgFeign;
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 java.util.*;

/**
 * title: FloorServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 楼层 服务层实现层
 *
 *
 *
 */
@Service
@RequiredArgsConstructor
public class FloorServiceImpl extends ServiceImpl<FloorMapper, Floor> implements FloorServiceInterface {

    private final ResidentialServiceInterface residentialServiceInterface;
    private final OrgFeign orgFeign;
    private final RedisTemplate<String,String> redisTemplate;
    private final BuildingServiceInterface buildingServiceInterface;
    private final UnitServiceInterface unitServiceInterface;

    @Autowired
    @Lazy
    private AccessCardServiceInterface accessCardServiceInterface;

    private final static String IMPORT_CACHE_UNIT_CODE_NAME = "sptg:import:floor:code:name";

    private final static String IMPORT_CACHE_UNIT_CODE = "sptg:import:card:floor:code";

    @Override
    public ResultBean<Page<Floor>> showFloorList(FloorDto floorDto) {
        // 构建查询条件
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        //过滤删除
        if (floorDto.getStatus() != null){
            wrapper.eq("i_status", floorDto.getStatus());
        }else {
            wrapper.eq("i_status", OperationConstant.ZERO);
        }
        //根据机构
        if (StringUtils.isNotBlank(floorDto.getOrgPosition())) {
            wrapper.like("s_org_position", floorDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if (StringUtils.isNotBlank(floorDto.getEstatePosition())) {
            wrapper.like("s_estate_position", floorDto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据编号查询
//        if (StringUtils.isNotBlank(floorDto.getFloorNumber())) {
//            wrapper.eq("s_floor_number", floorDto.getFloorNumber());
//        }
        //根据名字查询
        if (StringUtils.isNotBlank(floorDto.getName())) {
            wrapper.like("s_name", floorDto.getName(),SqlLike.DEFAULT);
        }
        //根据id查询
        if (floorDto.getId() != null) {
            wrapper.eq("l_id", floorDto.getId());
        }
        //根据小区ID查询
        if (floorDto.getResidentialId() != null){
            wrapper.eq("l_residential_id",floorDto.getResidentialId());
        }
        //根据小区ID查询
        if (floorDto.getBuildingId() != null){
            wrapper.eq("building_id",floorDto.getBuildingId());
        }
        //根据小区名称查询
        if (StringUtils.isNotBlank(floorDto.getResidentialName())) {
            wrapper.like("s_residential_name", floorDto.getResidentialName(),SqlLike.DEFAULT);
        }
        //根据单元ID查询
        if (floorDto.getUnitId() != null){
            wrapper.eq("unit_id",floorDto.getUnitId());
        }
        //排序
        if (floorDto.getSortField() != null && floorDto.getSortOrder() != null){
            wrapper.orderBy(floorDto.getSortField(),floorDto.getSortOrder().equals("asc"));
        }else {
            wrapper.orderAsc(Collections.singleton("i_serial"));
        }
        wrapper.orderDesc(Arrays.asList("l_residential_id","t_create_date","l_id"));
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(floorDto.getPage(), wrapper));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<FloorDto> addFloor(FloorDto floorDto) {
        //单元
        Unit unit = this.unitServiceInterface.findUnitById(floorDto.getUnitId());
        if(null == unit){
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        floorDto.setUnitName(unit.getName());

        //楼栋
        Building building = this.buildingServiceInterface.findBuildingById(unit.getBuildingId());
        if(null == building){
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        floorDto.setBuildingId(unit.getBuildingId());
        floorDto.setBuildingName(building.getName());

        //小区
        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
        if(null == residential){
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        floorDto.setResidentialId(residential.getId());
        floorDto.setResidentialName(residential.getName());
        floorDto.setRootOrgId(residential.getRootOrgId());


        //如果传入的序号为空则设置为1
        if (floorDto.getSerial() == null){
            floorDto.setSerial(OperationConstant.ONE);
        }
//        if(this.findFloorByCondition(floorDto) > 0){
//            return new ResultBean<>(EstateEnum.UNTI_DATA_EXISTES);
//        }


        floorDto.setRoomNumber(OperationConstant.ZERO);
        floorDto.setUserNumber(OperationConstant.ZERO);
        floorDto.setRootOrgId(residential.getRootOrgId());
        floorDto.setCreateDate(new Date());
        floorDto.setStatus(OperationConstant.ZERO);

        boolean insert = this.insert(floorDto);
        if(insert){
            floorDto.setOrgPosition(unit.getOrgPosition()+floorDto.getId()+"/");
            this.updateById(floorDto);
            return new ResultBean<>(ResultEnum.SUCCESS,floorDto);
        }

        return new ResultBean<>(ResultEnum.ERROR);
    }

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

    @Override
    public ResultBean<Boolean> updateFloor(FloorDto floorDto) {
        return new ResultBean<>(ResultEnum.SUCCESS,this.updateById(floorDto));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteFloor(FloorDto floorDto) {
        Floor floor = this.findFloorById(floorDto.getId());
        if(null == floor){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(floor.getResidentialId());
        if(null == residential){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        if(floor.getRoomNumber() > 0 || floor.getUserNumber() >0 ){
            return new ResultBean<>(EstateEnum.HAVE_CHILDREN);
        }
        floor.setStatus(floorDto.getStatus());
        if(this.updateById(floor)){
            //小区楼层数量-1
//            residential.setFloorNumber(residential.getFloorNumber()-1);
            if(this.residentialServiceInterface.updateById(residential)){
                //删除关联卡及下发的卡号
                if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(floor.getId(),OperationConstant.TWO)){
                    this.deleteCache(floor);
                    return new ResultBean<>(ResultEnum.SUCCESS,true);
                }
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> trashOrRecover(FloorDto floorDto) {
        Floor floor = this.findFloorById(floorDto.getId());
        if(null == floor){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(floor.getResidentialId());
        if(null == residential){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        floor.setStatus(floorDto.getStatus());
        if(this.updateById(floor)){
            //删除关联卡及下发的卡号
            if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(floor.getId(),OperationConstant.TWO)){
                this.deleteCache(floor);
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteFloorList(FloorDto floorDto) throws Exception {
        List<String> ids = floorDto.getIds();
        String msg ;
        for(String id : ids){
            Floor floor = this.findFloorById(Long.valueOf(id));
            if(null == floor){
                msg = "楼层不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            Residential residential = this.residentialServiceInterface.findResidentialById(floor.getResidentialId());
            if(null == residential){
                msg = floor.getName()+"楼层所属小区不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            if(floor.getRoomNumber() > 0 || floor.getUserNumber() >0 ){
                msg = floor.getName()+"楼层含有下级数据，请核实后重新操作";
                throw new Exception(msg);
            }
            floor.setStatus(OperationConstant.MINUS_ONE);
            if(this.updateById(floor)){
                //小区楼层数量-1
//                residential.setFloorNumber(residential.getFloorNumber()-1);
                if(this.residentialServiceInterface.updateById(residential)){
                    //删除关联卡及下发的卡号
                   if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(floor.getId(),OperationConstant.TWO)){
                       this.deleteCache(floor);
                   }else{
                       msg = residential.getName()+"楼层关联卡删除失败，请核实后重新操作";
                       throw new Exception(msg);
                   }
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

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

    @Override
    public ResultBean<Floor> findListByPid(FloorDto floorDto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        wrapper.eq("l_org_pid", floorDto.getOrgPid());
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectList(wrapper));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> importFloorList(FloorDto floorDto){
//        List<Floor> list = floorDto.getList();
//        if(this.insertBatch(list,500)){
//            Map<Long,Integer> map = floorDto.getMap();
//            for (Map.Entry<Long, Integer> entry : map.entrySet()) {
//               Residential residential = this.residentialServiceInterface.findResidentialById(entry.getKey());
//               residential.setFloorNumber(residential.getFloorNumber() + entry.getValue());
//               this.residentialServiceInterface.updateById(residential);
//            }
//        }
        return  new ResultBean<>(ExcelResultEnum.SUCCESS,true);
    }

    @Override
    public Floor findFloorByNameAndNumber(FloorDto floorDto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
//        //过滤删除
//        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
//        wrapper.eq("l_residential_id",floorDto.getResidentialId());
//        if(StringUtils.isNotBlank(floorDto.getName())){
//            //名称
//            wrapper.eq("s_name",floorDto.getName());
//        }
//        if(StringUtils.isNotBlank(floorDto.getFloorNumber())){
//            //编号
//            wrapper.eq("s_floor_number",floorDto.getFloorNumber());
//        }
        return this.selectOne(wrapper);
    }

    @Override
    public int getFloorAccount(FloorDto floorDto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.like("s_org_position",floorDto.getOrgPosition(),SqlLike.RIGHT);
        //当月新增
        if(OperationConstant.TWO == floorDto.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 int findFloorByCondition(FloorDto floorDto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //过滤自己
        if(null != floorDto.getId()){
            wrapper.notIn("l_id",floorDto.getId());
        }
        return this.baseMapper.findFloorByCondition(floorDto,wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Floor addFloorByImport(Floor floor) {
        Residential residential = this.residentialServiceInterface.findResidentialById(floor.getResidentialId());
        if(null == residential){
            return null;
        }
        floor.setResidentialId(residential.getId());
        floor.setResidentialName(residential.getName());
        floor.setRootOrgId(residential.getRootOrgId());
        floor.setOrgPid(residential.getId());
        floor.setOrgPidName(residential.getName());
        floor.setId(IdWorker.getId());
        //保存楼层位置
        floor.setOrgPosition(residential.getOrgPosition() + floor.getId() + SymbolConstant.BACK_SLASH);
        floor.setEstatePosition(residential.getEstatePosition() + floor.getId() + SymbolConstant.BACK_SLASH);
        floor.setRoomNumber(OperationConstant.ZERO);
        floor.setUserNumber(OperationConstant.ZERO);
        floor.setRootOrgId(residential.getRootOrgId());
        floor.setCreateDate(new Date());
        floor.setStatus(OperationConstant.ZERO);
//        if(this.insert(floor)){
//            //小区楼层数量加+1
//            residential.setFloorNumber(residential.getFloorNumber() + 1);
//            if(this.residentialServiceInterface.updateById(residential)){
//                return floor;
//            }
//        }
        return null;
    }

    @Override
    public List<Floor> getListByLikeName(FloorDto dto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        if(dto != null){
            if (dto.getId() != null){
                wrapper.eq("l_id",dto.getId());
            }
            if (StringUtils.isNotBlank(dto.getName())){
                wrapper.like("s_name",dto.getName(),SqlLike.DEFAULT);
            }
            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.RIGHT);
            }
            if (dto.getResidentialId() != null){
                wrapper.eq("l_residential_id",dto.getResidentialId());
            }
            if (dto.getIsSelect()){
                wrapper.last("limit 10");
            }
        }

        return this.selectList(wrapper);
    }

    @Override
    public Floor findByFloorNumber(String floorNumber) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        if (floorNumber != null){
            wrapper.eq("s_floor_number", floorNumber);
            return this.selectOne(wrapper);
        }else{
            return null;
        }

    }

    @Override
    public Floor findByOldId(String oldId) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        wrapper.eq("old_id",oldId);
        return this.selectOne(wrapper);
    }

    @Override
    public int addFloorSync(Floor floor) {
        if(this.insert(floor)){
            return 1;
        }
        return 0;
    }

    @Override
    public int updateFloorSync(Floor floor) {
        if(this.updateById(floor)){
            return 1;
        }
        return 0;
    }

    @Override
    public List<Floor> getFloorByUnitId(Long unitId) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        wrapper.eq("unit_id", unitId);
        return this.selectList(wrapper);
    }

    @Override
    public List<Floor> getListByCondition(FloorDto floorDto) {
        Wrapper<Floor> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        //名称
        if (StringUtils.isNotBlank(floorDto.getName())){
            wrapper.eq("s_name", floorDto.getName());
        }
        //小区id
        if (floorDto.getResidentialId() != null){
            wrapper.eq("l_residential_id", floorDto.getResidentialId());
        }
        //楼栋id
        if (floorDto.getBuildingId() != null){
            wrapper.eq("building_id", floorDto.getBuildingId());
        }
        //单元id
        if (floorDto.getUnitId() != null){
            wrapper.eq("unit_id", floorDto.getUnitId());
        }
        //机构路径
        if (StringUtils.isNotBlank(floorDto.getOrgPosition())){
            wrapper.like("s_org_position", floorDto.getOrgPosition());
        }

        return this.selectList(wrapper);
    }

    /* -------------------------------------------------- 内部方法 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------- */
    /**
     * 功能描述:删除缓存
     * @param floor
     *
     *
     */
    private void deleteCache(Floor floor){
        HashOperations<String, String, String> hashOperations = this.redisTemplate.opsForHash();
//        long residentialId = floor.getResidentialId();
//        String floorName = floor.getName();
//        String floorNumber = floor.getFloorNumber();
//        StringBuffer sb = new StringBuffer(residentialId + "-"+floorName+"-"+floorNumber);
//        String hashKey = sb.toString();
//        String json = hashOperations.get(IMPORT_CACHE_UNIT_CODE_NAME,hashKey);
//        if (!StringUtils.isEmpty(json)) {
//            hashOperations.delete(IMPORT_CACHE_UNIT_CODE_NAME,hashKey);
//        }
//        sb = new StringBuffer(residentialId+""+floorNumber);
//        hashKey = sb.toString();
//        json = hashOperations.get(IMPORT_CACHE_UNIT_CODE,hashKey);
//        if (!StringUtils.isEmpty(json)) {
//            hashOperations.delete(IMPORT_CACHE_UNIT_CODE,hashKey);
//        }
    }
}
