package ink.wgink.mongo.module.dictionary.service.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.dictionary.pojo.dtos.AreaDTO;
import ink.wgink.module.dictionary.service.IAreaService;
import ink.wgink.mongo.module.dictionary.enums.MongoDictionaryCollectionEnum;
import ink.wgink.mongo.module.dictionary.service.IMongoAreaService;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.ZTreeDTO;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.string.WStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @ClassName: AreaServiceImpl
 * @Description: 字典
 * @Author: WangGeng
 * @Date: 2019/11/18 14:09
 * @Version: 1.0
 **/
@Service
public class MongoAreaServiceImpl extends DefaultBaseService implements IMongoAreaService {

    @Autowired
    private IAreaService areaService;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void updateMongo() {
        List<AreaDTO> dataDTOs = areaService.list();
        mongoTemplate.remove(new Query(), MongoDictionaryCollectionEnum.AREA.getValue());
        mongoTemplate.insert(dataDTOs, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    @Override
    public AreaDTO get(String areaId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("areaId").is(areaId)), AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    @Override
    public AreaDTO getByCode(String areaCode) {
        return mongoTemplate.findOne(Query.query(Criteria.where("areaCode").is(areaCode)), AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    @Override
    public List<AreaDTO> listByParentId(String areaParentId) {
        return mongoTemplate.find(Query.query(Criteria.where("areaParentId").is(areaParentId)), AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    @Override
    public List<AreaDTO> listAllByParentId(String areaParentId) {
        List<AreaDTO> areaDTOs = listByParentId(areaParentId);
        listSub(areaDTOs);
        return areaDTOs;
    }

    @Override
    public SuccessResultList<List<AreaDTO>> listPage(ListPage page) {
        Query query = new Query(Criteria.where("areaParentId").is(page.getParams().get("areaParentId").toString()));
        String keywords = getKeywords(page.getParams());
        if (!StringUtils.isBlank(keywords)) {
            Pattern pattern = Pattern.compile("^.*" + keywords + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("areaName").regex(pattern));
        }
        long total = mongoTemplate.count(query, MongoDictionaryCollectionEnum.AREA.getValue());
        query.with(Pageable.ofSize(page.getRows()).withPage(page.getPage() - 1));
        List<AreaDTO> dataDTOs = mongoTemplate.find(query, AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
        return new SuccessResultList<>(dataDTOs, page.getPage(), total);
    }

    @Override
    public List<ZTreeDTO> listZTree(String areaParentId) {
        List<AreaDTO> areaDTOs = listByParentId(areaParentId);
        List<ZTreeDTO> zTreeDTOs = new ArrayList<>();
        for (AreaDTO areaDTO : areaDTOs) {
            ZTreeDTO zTreeDTO = new ZTreeDTO();
            zTreeDTO.setId(areaDTO.getAreaId());
            zTreeDTO.setpId(areaDTO.getAreaParentId());
            zTreeDTO.setName(areaDTO.getAreaName());
            long subCount = mongoTemplate.count(Query.query(Criteria.where("areaParentId").is(areaDTO.getAreaId())), MongoDictionaryCollectionEnum.AREA.getValue());
            setZTreeInfo(zTreeDTO, subCount);
            zTreeDTOs.add(zTreeDTO);
        }
        return zTreeDTOs;
    }

    @Override
    public List<AreaDTO> listByCode(String areaCode) {
        Pattern pattern = Pattern.compile("^" + areaCode + ".*$", Pattern.CASE_INSENSITIVE);
        return mongoTemplate.find(Query.query(Criteria.where("areaCode").regex(pattern)), AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    @Override
    public List<AreaDTO> listSubByCode(String areaCode) {
        String baseAreaCode = WStringUtil.cutContinuityRepeatCharDesc(areaCode, '0', 3);
        Pattern pattern = Pattern.compile("^" + baseAreaCode + "((?!" + areaCode.replace(baseAreaCode, "") + ").)*$", Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        query.addCriteria(Criteria.where("areaCode").regex(pattern));
        return mongoTemplate.find(query, AreaDTO.class, MongoDictionaryCollectionEnum.AREA.getValue());
    }

    /**
     * 递归查询子组
     *
     * @param areaDTOs
     */
    private void listSub(List<AreaDTO> areaDTOs) {
        for (AreaDTO areaDTO : areaDTOs) {
            List<AreaDTO> subAreaDTOs = listByParentId(areaDTO.getAreaId());
            areaDTO.setSubArea(subAreaDTOs);
            listSub(subAreaDTOs);
        }
    }

}
