package com.yuchen.saas.park.service.service.property;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkunion.park.service.common.utils.PingYinUtil;
import com.thinkunion.park.service.common.utils.StringGenerator;
import com.yuchen.saas.park.api.dto.property.PropertyBuildingsQryDto;
import com.yuchen.saas.park.api.dto.property.PropertyBuildingsSaveDto;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.vo.property.PropertyBuildingsListVo;
import com.yuchen.saas.park.service.mapper.property.PropertyBuildingsMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.tool.constant.NestConstant;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class PropertyBuildingsService extends BaseServiceImpl<PropertyBuildingsMapper, PropertyBuildings> {
    @Autowired
    private PropertyBuildingUnitService propertyBuildingUnitService;
    @Lazy
    @Autowired
    private PmgBatParkInfoService pmgBatParkInfoService;
    @Lazy
    @Autowired
    private PropertyHousesService propertyHousesService;
    @Autowired
    private PropertySearchParkInfoService propertySearchParkInfoService;

    /**
     * 楼栋保存
     *
     * @param propertyBuildings
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveBuilding(PropertyBuildingsSaveDto propertyBuildings) {
        this.verifySaveBuilding(propertyBuildings);
        this.assemblePropertyBuildings(propertyBuildings);
        this.saveOrUpdate(propertyBuildings);
        this.saveBuildingUnit(propertyBuildings.getUnitNumList(), propertyBuildings.getId());
    }

    /**
     * 组装保存对象
     *
     * @param propertyBuildings
     */
    private void assemblePropertyBuildings(PropertyBuildingsSaveDto propertyBuildings) {
        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(propertyBuildings.getParkId());
        String pn = PingYinUtil.getPinYinHeadCharUpper(parkInfo.getParkName());
        String bn = PingYinUtil.getPinYinHeadCharUpper(propertyBuildings.getBuildingName());
        String resourceCode = pn + "-" + bn; // 园区名称拼音首字母 + 楼栋名称拼音首字母

        LambdaQueryWrapper<PropertyBuildings> qw = new LambdaQueryWrapper<>();
        qw.eq(PropertyBuildings::getParkId, propertyBuildings.getParkId());
        qw.eq(PropertyBuildings::getResourceCode, resourceCode);
        PropertyBuildings building = this.getOne(qw);
        if (building != null) { // 如果已存在拼两位随机数
            resourceCode += StringGenerator.GetRandomString(2);
        }

        propertyBuildings.setResourceCode(resourceCode);

    }

    /**
     * 楼栋保存校验
     *
     * @param propertyBuildings
     */
    private void verifySaveBuilding(PropertyBuildingsSaveDto propertyBuildings) {
        LambdaQueryWrapper<PropertyBuildings> qw3 = new LambdaQueryWrapper<>();
        qw3.eq(PropertyBuildings::getParkId, propertyBuildings.getParkId());
        qw3.eq(PropertyBuildings::getIsDeleted, NestConstant.DB_NOT_DELETED);
        qw3.eq(PropertyBuildings::getBuildingName, propertyBuildings.getBuildingName());
        PropertyBuildings building3 = this.getOne(qw3);
        if (building3 != null) {
            if (Func.isEmpty(propertyBuildings.getId())
                    || !building3.getId().equals(propertyBuildings.getId())) {
                throw new ServiceException("楼栋名称已存在");
            }
        }
/*
        if (Func.isNotEmpty(propertyBuildings.getId())) {
            LambdaQueryWrapper<PropertyHouses> houseQry = new LambdaQueryWrapper();
            houseQry.eq(PropertyHouses::getBuildingId, propertyBuildings.getId());
            houseQry.select(PropertyHouses::getUnitNum);
            houseQry.groupBy(PropertyHouses::getUnitNum);
            List<PropertyHouses> housesList = propertyHousesService.list(houseQry);
            housesList.forEach(house -> {
                if (!propertyBuildings.getUnitNumList().contains(house.getUnitNum())) {
                    throw new ServiceException("单元号[" + house.getUnitNum() + "]已被引用，不能删除");
                }
            });
        }
*/
    }

    private void saveBuildingUnit(Set<String> unitNumSet, Long buildingId) {
        if (buildingId != null) {
            LambdaQueryWrapper<PropertyBuildingUnit> qw = new LambdaQueryWrapper<>();
            qw.eq(PropertyBuildingUnit::getBuildingId, buildingId);
            propertyBuildingUnitService.remove(qw);
        }

        List<PropertyBuildingUnit> list = new ArrayList<>();
        unitNumSet.forEach(unitNum -> {
            PropertyBuildingUnit buildingUnit = new PropertyBuildingUnit();
            buildingUnit.setBuildingId(buildingId);
            buildingUnit.setUnitNum(unitNum);
            buildingUnit.setCreateTime(new Date());
            list.add(buildingUnit);
        });

        propertyBuildingUnitService.saveBatch(list);
    }


    /**
     * 楼栋分页查询
     *
     * @param req
     * @return
     */
    public Page<PropertyBuildingsListVo> selectPage(PropertyBuildingsQryDto req) {
        Page<PropertyBuildingsListVo> page = new Page<>(req.getCurrent(), req.getSize());
        baseMapper.propertyBuildingsPage(page, this.getPageQueryParam(req));
        this.decoratePropertyBuildingsList(page.getRecords());
        return page;
    }


    /**
     * 列表数据装饰
     *
     * @param records
     */
    private void decoratePropertyBuildingsList(List<PropertyBuildingsListVo> records) {
        List<Long> buildingIdList = records.stream().map(PropertyBuildingsListVo::getId).collect(Collectors.toList());
        if (buildingIdList.size() == 0) {
            return;
        }
        // 统计楼栋单元数
        LambdaQueryWrapper<PropertyBuildingUnit> qw = new LambdaQueryWrapper<>();
        qw.in(PropertyBuildingUnit::getBuildingId, buildingIdList);
        List<PropertyBuildingUnit> buildingUnitList = propertyBuildingUnitService.list(qw);
        records.forEach(record -> {
            List<String> unitNumList = new ArrayList<>();
            buildingUnitList.forEach(buildingUnit -> {
                if (record.getId().equals(buildingUnit.getBuildingId())) {
                    unitNumList.add(buildingUnit.getUnitNum());
                }
            });
            record.setUnitNumList(unitNumList);
        });

    }


    /**
     * 分页查询条件
     *
     * @param req
     * @return
     */
    private LambdaQueryWrapper<PropertyBuildings> getPageQueryParam(PropertyBuildingsQryDto req) {
        LambdaQueryWrapper<PropertyBuildings> qw = new LambdaQueryWrapper<>();
        if (Func.isNotEmpty(req.getParkId())) {
            qw.eq(PropertyBuildings::getParkId, req.getParkId());
        } else {
            qw.in(PropertyBuildings::getParkId,propertySearchParkInfoService.getParkIdsByCurrUser());
        }
        if (StringUtil.isNotBlank(req.getBuildingName())) {
            qw.like(PropertyBuildings::getBuildingName, req.getBuildingName());
        }
        if (Func.isNotEmpty(req.getHeightType())) {
            qw.eq(PropertyBuildings::getHeightType, req.getHeightType());
        }
        if (Func.isNotEmpty(req.getUseType())) {
            qw.eq(PropertyBuildings::getUseType, req.getUseType());
        }
        if (Func.isNotEmpty(req.getTowardType())) {
            qw.eq(PropertyBuildings::getTowardType, req.getTowardType());
        }
        qw.eq(PropertyBuildings::getIsDeleted, NestConstant.DB_NOT_DELETED);
        return qw;
    }

    /**
     * 楼栋详情
     * @param buildingId
     * @return
     */
    public PropertyBuildingsSaveDto getBuildingDetail(Long buildingId) {
        PropertyBuildings buildings = this.getById(buildingId);
        PropertyBuildingsSaveDto detail = BeanUtil.copyProperties(buildings, PropertyBuildingsSaveDto.class);
        List<String> unitNumList = propertyBuildingUnitService.lambdaQuery()
                .eq(PropertyBuildingUnit::getBuildingId, buildingId).list().stream()
                .map(PropertyBuildingUnit::getUnitNum).collect(Collectors.toList());
        if (unitNumList != null) {
            detail.setUnitNumList(new HashSet<>(unitNumList));
        }
        return detail;
    }

    /**
     * 楼栋删除
     * @param buildingId
     * @return
     */
    public boolean del(Long buildingId) {
       int count = propertyHousesService.lambdaQuery().eq(PropertyHouses::getBuildingId,buildingId).count();
       if (count > 0) {
           throw new ServiceException("该楼栋已被其它房源引用，请先删除相关房源信息");
       }
       return this.removeById(buildingId);
    }


    public List<PropertyBuildings> getAll(Long parkId) {
        if(Func.isEmpty(parkId)){
            return baseMapper.getAllBuildings();
        }
        return baseMapper.getAll(parkId);
    }

}
