package com.cm.common.plugin.service.dataarea.impl;

import com.cm.common.base.AbstractService;
import com.cm.common.exception.RemoveException;
import com.cm.common.exception.SearchException;
import com.cm.common.plugin.dao.dataarea.IDataAreaDao;
import com.cm.common.plugin.pojo.dtos.dataarea.DataAreaDTO;
import com.cm.common.plugin.pojo.vos.dataarea.DataAreaVO;
import com.cm.common.plugin.service.dataarea.IDataAreaService;
import com.cm.common.pojo.ListPage;
import com.cm.common.pojo.dtos.ZTreeDTO;
import com.cm.common.result.SuccessResult;
import com.cm.common.result.SuccessResultList;
import com.cm.common.utils.HashMapUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: AreaServiceImpl
 * @Description: 字典
 * @Author: WangGeng
 * @Date: 2019/11/18 14:09
 * @Version: 1.0
 **/
@Service
public class DataAreaServiceImpl extends AbstractService implements IDataAreaService {

    @Autowired
    private IDataAreaDao dataArea;

    @Override
    public SuccessResult saveArea(DataAreaVO dataAreaVO) throws Exception {
        saveAreaInfo(null, dataAreaVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult saveArea(String token, DataAreaVO dataAreaVO) throws Exception {
        saveAreaInfo(token, dataAreaVO);
        return new SuccessResult();
    }

    @Override
    public String saveAreaReturnId(DataAreaVO dataAreaVO) throws Exception {
        return saveAreaInfo(null, dataAreaVO);
    }

    @Override
    public String saveAreaReturnId(String token, DataAreaVO dataAreaVO) throws Exception {
        return saveAreaInfo(token, dataAreaVO);
    }

    private String saveAreaInfo(String token, DataAreaVO dataAreaVO) throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(dataAreaVO);
        if (StringUtils.isBlank(token)) {
            setSaveInfo(params);
        } else {
            setSaveInfo(token, params);
        }
        dataArea.saveArea(params);
        return params.get("areaId").toString();
    }

    @Override
    public SuccessResult removeArea(String ids) throws RemoveException {
        removeAreaInfo(null, ids);
        return new SuccessResult();
    }

    @Override
    public SuccessResult removeArea(String token, String ids) throws RemoveException {
        removeAreaInfo(token, ids);
        return new SuccessResult();
    }

    private void removeAreaInfo(String token, String ids) {
        Map<String, Object> params = getHashMap(3);
        params.put("areaIds", Arrays.asList(ids.split("_")));
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setUpdateInfo(token, params);
        }
        dataArea.removeArea(params);
    }

    @Override
    public SuccessResult updateArea(String areaId, DataAreaVO dataAreaVO) throws Exception {
        updateAreaInfo(null, areaId, dataAreaVO);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updateArea(String token, String areaId, DataAreaVO dataAreaVO) throws Exception {
        updateAreaInfo(token, areaId, dataAreaVO);
        return new SuccessResult();
    }

    private void updateAreaInfo(String token, String areaId, DataAreaVO dataAreaVO) throws Exception {
        Map<String, Object> params = HashMapUtil.beanToMap(dataAreaVO);
        params.put("areaId", areaId);
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setUpdateInfo(token, params);
        }
        dataArea.updateArea(params);
    }

    @Override
    public DataAreaDTO getAreaById(String areaId) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("areaId", areaId);
        return dataArea.getArea(params);
    }

    @Override
    public List<DataAreaDTO> listAreaByParentId(String dataAreaParentId) throws SearchException {
        Map<String, Object> params = getHashMap(1);
        params.put("areaParentId", dataAreaParentId);
        return dataArea.listArea(params);
    }

    @Override
    public List<DataAreaDTO> listAreaAllByParentId(String dataAreaParentId) throws SearchException {
        Map<String, Object> params = getHashMap(1);
        params.put("areaParentId", dataAreaParentId);
        List<DataAreaDTO> dataAreaDTOs = dataArea.listArea(params);
        listSubAreas(dataAreaDTOs, params);
        return dataAreaDTOs;
    }

    @Override
    public SuccessResultList<List<DataAreaDTO>> listPageArea(ListPage page) throws SearchException {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<DataAreaDTO> dataAreaDTOs = dataArea.listArea(page.getParams());
        PageInfo<DataAreaDTO> pageInfo = new PageInfo<>(dataAreaDTOs);
        return new SuccessResultList<>(dataAreaDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public List<ZTreeDTO> listZTreeArea(Map<String, Object> params) throws SearchException {
        List<ZTreeDTO> zTreeDTOs = dataArea.listZTreeArea(params);
        for (ZTreeDTO zTreeDTO : zTreeDTOs) {
            Integer subCount = dataArea.countByParentId(zTreeDTO.getId());
            setZTreeInfo(zTreeDTO, subCount);
        }
        return zTreeDTOs;
    }

    @Override
    public List<DataAreaDTO> listAreaByAreaCode(String areaCode) throws SearchException {
        Map<String, Object> params = getHashMap(1);
        params.put("areaCode", areaCode);
        return dataArea.listArea(params);
    }

    /**
     * 递归查询子组
     *
     * @param dataAreaDTOs
     * @param params
     */
    private void listSubAreas(List<DataAreaDTO> dataAreaDTOs, Map<String, Object> params) throws SearchException {
        for (DataAreaDTO dataAreaDTO : dataAreaDTOs) {
            params.put("areaParentId", dataAreaDTO.getAreaId());
            List<DataAreaDTO> subDataAreaDTOS = dataArea.listArea(params);
            dataAreaDTO.setSubArea(subDataAreaDTOS);
            listSubAreas(subDataAreaDTOS, params);
        }
    }
}
