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.UnitDto;
import com.sptg.estate.api.entity.Building;
import com.sptg.estate.api.entity.Residential;
import com.sptg.estate.api.entity.Unit;
import com.sptg.estate.api.enums.EstateEnum;
import com.sptg.estate.biz.mapper.UnitMapper;
import com.sptg.estate.biz.service.AccessCardServiceInterface;
import com.sptg.estate.biz.service.BuildingServiceInterface;
import com.sptg.estate.biz.service.ResidentialServiceInterface;
import com.sptg.estate.biz.service.UnitServiceInterface;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.feigns.OrgFeign;
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.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * title: UnitServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 单元 服务层实现层
 *
 *
 *
 */
@Service
//@RequiredArgsConstructor
public class UnitServiceImpl extends ServiceImpl<UnitMapper, Unit> implements UnitServiceInterface {

    @Autowired
    private ResidentialServiceInterface residentialServiceInterface;
    @Autowired
    private BuildingServiceInterface buildingServiceInterface;
    @Autowired
    private OrgFeign orgFeign;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    @Lazy
    private AccessCardServiceInterface accessCardServiceInterface;

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

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

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

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<UnitDto> addUnit(UnitDto unitDto) {

        Building building = this.buildingServiceInterface.findBuildingById(unitDto.getBuildingId());
        if (null == building){
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(unitDto.getResidentialId());

        if(null == residential){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        unitDto.setResidentialId(residential.getId());
        unitDto.setResidentialName(residential.getName());
        unitDto.setRootOrgId(residential.getRootOrgId());
        //如果传入的序号为空则设置为1
        if (unitDto.getSerial() == null){
            unitDto.setSerial(OperationConstant.ONE);
        }
        List<Unit> units = this.getListByCondition(unitDto);
        if(units != null && units.size() > 0){
            return new ResultBean<>(EstateEnum.UNTI_DATA_EXISTES);
        }
        String orgPosition;
        if(null != unitDto.getOrgPid()){
            Organization organization = this.orgFeign.getOrgById(unitDto.getOrgPid());
            if(null == organization){
                return new ResultBean<>(ResultEnum.ERROR);
            }
            unitDto.setOrgPidName(organization.getName());
            orgPosition = organization.getPosition();
        }else{
            unitDto.setOrgPid(residential.getId());
            unitDto.setOrgPidName(residential.getName());
            orgPosition = residential.getOrgPosition();
        }
//        unitDto.setId(IdWorker.getId()); // 这里生成的id跟数据库表的id主键自动递增冲突，直接覆盖了
        //保存单元位置
        unitDto.setOrgPosition(orgPosition + unitDto.getId() + SymbolConstant.BACK_SLASH);
        //************************保存物业路径
//        unitDto.setEstatePosition(residential.getEstatePosition() + unitDto.getId() + SymbolConstant.BACK_SLASH);
        //************************保存物业路径
        if (unitDto.getSerial() == null){
            unitDto.setSerial(OperationConstant.ONE);
        }
        unitDto.setRoomNumber(OperationConstant.ZERO);
        unitDto.setFloorNumber(OperationConstant.ZERO);
        unitDto.setUserNumber(OperationConstant.ZERO);
        unitDto.setRootOrgId(residential.getRootOrgId());
        unitDto.setCreateDate(new Date());
        unitDto.setStatus(OperationConstant.ZERO);
        if(this.insert(unitDto)){
            unitDto.setOrgPosition(building.getOrgPosition() + unitDto.getId() + SymbolConstant.BACK_SLASH);
            this.updateById(unitDto);
            //小区单元数量加+1
            residential.setUnitNumber(residential.getUnitNumber() + 1);
            if(this.residentialServiceInterface.updateById(residential)){
                //楼栋单元数加+1
                building.setUnitNumber(building.getUnitNumber() + 1);
                if (this.buildingServiceInterface.updateById(building)){
                    return new ResultBean<>(ResultEnum.SUCCESS,unitDto);
                }
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

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

    @Override
    public ResultBean<Boolean> updateUnit(UnitDto unitDto) {
        if(this.findUnitByCondition(unitDto) > 0){
            return new ResultBean<>(EstateEnum.UNTI_DATA_EXISTES);
        }
        if(this.updateById(unitDto)){
            return  new ResultBean<>(ResultEnum.SUCCESS,true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteUnit(UnitDto unitDto) {
        Unit unit = this.findUnitById(unitDto.getId());
        if(null == unit){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
        if(null == residential){
            return new ResultBean<>(ResultEnum.ERROR);
        }
        if(unit.getRoomNumber() > 0 || unit.getUserNumber() >0 ){
            return new ResultBean<>(EstateEnum.HAVE_CHILDREN);
        }
        unit.setStatus(unitDto.getStatus());
        if(this.updateById(unit)){
            //小区单元数量-1
            residential.setUnitNumber(residential.getUnitNumber()-1);
            if(this.residentialServiceInterface.updateById(residential)){
                //删除关联卡及下发的卡号
                if(this.accessCardServiceInterface.deleteAccessCardByIdAndType(unit.getId(),OperationConstant.TWO)){
                    this.deleteCache(unit);
                    return new ResultBean<>(ResultEnum.SUCCESS,true);
                }
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

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

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

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

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

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> importUnitList(UnitDto unitDto){
        List<Unit> list = unitDto.getList();
        if(this.insertBatch(list,500)){
            Map<Long,Integer> map = unitDto.getMap();
            for (Map.Entry<Long, Integer> entry : map.entrySet()) {
               Residential residential = this.residentialServiceInterface.findResidentialById(entry.getKey());
               residential.setUnitNumber(residential.getUnitNumber() + entry.getValue());
               this.residentialServiceInterface.updateById(residential);
            }
        }
        return  new ResultBean<>(ExcelResultEnum.SUCCESS,true);
    }

    @Override
    public Unit findUnitByNameAndNumber(UnitDto unitDto) {
        Wrapper<Unit> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        wrapper.eq("l_residential_id",unitDto.getResidentialId());
        if(StringUtils.isNotBlank(unitDto.getName())){
            //名称
            wrapper.eq("s_name",unitDto.getName());
        }
        if(StringUtils.isNotBlank(unitDto.getUnitNumber())){
            //编号
            wrapper.eq("s_unit_number",unitDto.getUnitNumber());
        }
        return this.selectOne(wrapper);
    }

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

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

    @Override
    public List<Unit> getListByLikeName(UnitDto dto) {
        Wrapper<Unit> 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.getBuildingId() != null){
                wrapper.eq("building_id",dto.getBuildingId());
            }
//            if (dto.getIsSelect()){
//                wrapper.last("limit 10");
//            }
        }

        return this.selectList(wrapper);
    }

    @Override
    public Unit findByUnitNumber(String unitNumber) {
        Wrapper<Unit> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        if (unitNumber != null){
            wrapper.eq("s_unit_number", unitNumber);
            return this.selectOne(wrapper);
        }else{
            return null;
        }

    }

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

    @Override
    public int addUnitSync(Unit unit) {
        if(this.insert(unit)){
            return 1;
        }
        return 0;
    }

    @Override
    public int updateUnitSync(Unit unit) {
        if(this.updateById(unit)){
            return 1;
        }
        return 0;
    }

    @Override
    public List<Unit> getListByBuildingId(Long buildingId) {
        Wrapper<Unit> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        wrapper.eq("building_id", buildingId);

        return this.selectList(wrapper);
    }

    @Override
    public List<Unit> getListByCondition(UnitDto unitDto) {
        Wrapper<Unit> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        //名称
        if (StringUtils.isNotBlank(unitDto.getName())){
            wrapper.eq("s_name", unitDto.getName());
        }

        //小区id
        if (unitDto.getResidentialId() != null){
            wrapper.eq("l_residential_id", unitDto.getResidentialId());
        }
        //楼栋id
        if (unitDto.getBuildingId() != null){
            wrapper.eq("building_id", unitDto.getBuildingId());
        }
        // 机构路径
        if (StringUtils.isNotBlank(unitDto.getOrgPosition())){
            wrapper.like("s_org_position", unitDto.getOrgPosition());
        }
        return this.selectList(wrapper);
    }

    /* -------------------------------------------------- 内部方法 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------- */
    /**
     * 功能描述:删除缓存
     * @param unit
     *
     *
     */
    private void deleteCache(Unit unit){
        HashOperations<String, String, String> hashOperations = this.redisTemplate.opsForHash();
        long residentialId = unit.getResidentialId();
        String unitName = unit.getName();
        String unitNumber = unit.getUnitNumber();
        StringBuffer sb = new StringBuffer(residentialId + "-"+unitName+"-"+unitNumber);
        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+""+unitNumber);
        hashKey = sb.toString();
        json = hashOperations.get(IMPORT_CACHE_UNIT_CODE,hashKey);
        if (!StringUtils.isEmpty(json)) {
            hashOperations.delete(IMPORT_CACHE_UNIT_CODE,hashKey);
        }
    }
}
