package com.ssm.manage.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssm.core.service.impl.BaseServiceImpl;
import com.ssm.core.utils.SnowflakeUtil;
import com.ssm.manage.dao.SsmProjectTypeDao;
import com.ssm.manage.entity.*;
import com.ssm.manage.mapper.BaseProjectTypeMapper;
import com.ssm.manage.query.ProjectTypeRequest;
import com.ssm.manage.query.StoreRequest;
import com.ssm.manage.response.ResponseCode;
import com.ssm.manage.response.StaffResponse;
import com.ssm.manage.service.SsmBaseStoreService;
import com.ssm.manage.service.SsmProjectService;
import com.ssm.manage.service.SsmProjectTypeService;
import com.ssm.manage.utils.Constant;
import com.ssm.util.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.StringEncoderComparator;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

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

@Service
@Slf4j
public class SsmProjectTypeServiceImpl extends BaseServiceImpl<BaseProjectType> implements SsmProjectTypeService {
    @Autowired
    private RedisClient<StaffResponse> templateRedisClient;

    @Autowired
    private SsmProjectService ssmProjectService;

    @Autowired
    private SsmBaseStoreService ssmBaseStoreService;

    @Autowired
    private SsmProjectTypeDao dao;

    @Override
    public SsmProjectTypeDao getDao() {
        return dao;
    }

    @Override
    public PageInfo<BaseProjectType> selectPage(ProjectTypeRequest projectTypeRequest) {
        StoreRequest storeRequest = new StoreRequest();
        storeRequest.setId(projectTypeRequest.getStoreId());
        List<BaseStores> pagesorganizations = ssmBaseStoreService.pagesorganizations(storeRequest);
        for (BaseStores pagesorganization : pagesorganizations) {
            if(null == pagesorganization.getParentId()){
                projectTypeRequest.setStoreId(pagesorganization.getId());
            }
        }
        return dao.selectPage(projectTypeRequest);
    }


    @Override
    public int addProjectType(ProjectTypeRequest projectTypeRequest,String key) throws SmsException {
        this.check(projectTypeRequest.getProjectTypeNum(), projectTypeRequest.getProjectTypeName(),projectTypeRequest.getStoreId());
        BaseProjectType projectType = new BaseProjectType();
        projectType.setId(new SnowflakeUtil(new Random().nextInt(1023)).nextId());
        projectType.setProjectTypeNum(projectTypeRequest.getProjectTypeNum());
        projectType.setProjectTypeName(projectTypeRequest.getProjectTypeName());
        projectType.setState(1);
        projectType.setStoreId(projectTypeRequest.getStoreId());
        projectType.setStoreName(projectTypeRequest.getStoreName());
        projectType.setParentId(projectTypeRequest.getParentId());
        if (templateRedisClient.hasKey(getKey(key))){
            StaffResponse staffResponse = templateRedisClient.get(getKey(key));
            projectType.setFounderStaff(staffResponse.getStaffName());
            projectType.setFounderDatetime(new Date());
        }
        return dao.saveNotNull(projectType);
    }

    @Override
    public int updateProjectType(ProjectTypeRequest projectTypeRequest, String key) throws SmsException {
        this.check(null, projectTypeRequest.getProjectTypeName(), projectTypeRequest.getStoreId(),projectTypeRequest.getId());
        if(null != projectTypeRequest.getParentId()){
            if(projectTypeRequest.getParentId()==projectTypeRequest.getId()){
                throw new SmsException(ResponseCode.NOT_EQUALS_REQUIREMENTS_S_new,"上级ID和本身");
            }
        }
        BaseProjectType projectType = new BaseProjectType();
        projectType.setId(projectTypeRequest.getId());
//        projectType.setProjectTypeNum(projectTypeRequest.getProjectTypeNum());
        projectType.setProjectTypeName(projectTypeRequest.getProjectTypeName());
        projectType.setParentId(projectTypeRequest.getParentId());
//        projectType.setStates(1);
//        projectType.setStoreId(projectTypeRequest.getStoreId());
//        projectType.setStoreName(projectTypeRequest.getStoreName());
        if (templateRedisClient.hasKey(getKey(key))){
            StaffResponse staffResponse = templateRedisClient.get(getKey(key));
            projectType.setModifyBy(staffResponse.getStaffName());
            projectType.setModifyDatetime(new Date());
        }
        return dao.updateByPrimaryKeySelective(projectType);
    }

    @Override
    public int deleteProjectType(ProjectTypeRequest projectTypeRequest) throws SmsException {
        BaseProjectType projectType = new BaseProjectType();
        projectType.setId(projectTypeRequest.getId());
        //查询当前项目类型是否存在在使用中的项目
        BaseProject project = new BaseProject();
        project.setProjectTypeId(projectTypeRequest.getId());
        project.setState(1);
        int i = ssmProjectService.selectCount(project);
        if (i > 0){
            throw new SmsException(ResponseCode.PRO_TYPE_EXIST_PRO,"删除");
        }
        BaseProjectType projectTypes = new BaseProjectType();
        projectTypes.setParentId(projectTypeRequest.getId());
        int size = dao.selectCount(projectTypes);
        if(size>0){
            throw new SmsException(ResponseCode.DATA_NOT_ALLOW_UPDATESSSS,"该类别存在下级，不允许删除");
        }

        return dao.deleteByPrimaryKey(projectType);
    }


    @Override
    public int updateStates(ProjectTypeRequest projectTypeRequest) throws SmsException {
        BaseProjectType projectType = new BaseProjectType();
        projectType.setId(projectTypeRequest.getId());
        projectType.setState(projectTypeRequest.getState());
        //查询当前项目类型是否存在在使用中的项目
        BaseProject project = new BaseProject();
        project.setProjectTypeId(projectTypeRequest.getId());
        project.setState(1);
        int i = ssmProjectService.selectCount(project);
        if (i > 0){
            throw new SmsException(ResponseCode.PRO_TYPE_EXIST_PRO,"启用停用");
        }
        return dao.updateByPrimaryKeySelective(projectType);
    }


    @Override
    public List<BaseProjectType> list(Long storeId) {
//        BaseProjectType projectType = new BaseProjectType();
//        projectType.setStoreId(storeId);
//        return dao.select(projectType);
        StoreRequest storeRequest = new StoreRequest();
        storeRequest.setId(storeId);
        List<BaseStores> pagesorganizations = ssmBaseStoreService.pagesorganizations(storeRequest);
        for (BaseStores pagesorganization : pagesorganizations) {
            if(null == pagesorganization.getParentId()){
                storeId=pagesorganization.getId();
            }
        }

        Example example = new Example(BaseProjectType.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("project_type_num desc");
        criteria.andEqualTo("storeId", storeId);
        PageHelper.orderBy("project_type_num");
        List<BaseProjectType> list = selectByExample(example);
        return list;
    }

    @Override
    public List<ProjectTypeRequest> getMenu(ProjectTypeRequest projectTypeRequest) {
        return dao.getMenu(projectTypeRequest);
    }

    @Override
    public List<ProjectTypeRequest> getMenuId(ProjectTypeRequest projectTypeRequest) {
        List<ProjectTypeRequest> allRecursions = dao.getMenuId(projectTypeRequest);
        List<ProjectTypeRequest> baseStoress = new ArrayList<>();
        List<ProjectTypeRequest> recursions = this.recursion(allRecursions,baseStoress);
//        for (int i = 0; i < recursions.size(); i++) {
//            if(storeRequest.getId().longValue() == recursions.get(i).getId().longValue()){
//                recursions.remove(i);
//                continue;
//            }
//        }
        //recursions.add(baseStores1);

        return recursions;
    }

    /**
     * 递归评级
     * @param allRecursion
     * @return
     */
    public List<ProjectTypeRequest> recursion(List<ProjectTypeRequest> allRecursion,List<ProjectTypeRequest> baseStore){
        for (ProjectTypeRequest baseStores : allRecursion) {
            if (baseStores.getProjectTypeRequestList().size() > 0) {
                recursion(baseStores.getProjectTypeRequestList(), baseStore);
            }
            if (baseStores != null) {
                //allRecursion.remove(baseStores);
                baseStore.add(baseStores);
            }
        }
        return baseStore;
    }
    @Override
    public List<BaseProjectType> insertBatch(List<BaseProjectType> list, Long storeId, String storeName, String key) throws SmsException {
        int i = 0;
        try {
            List<BaseProjectType> unusualList = this.check(list);
            if (!unusualList.isEmpty()){
                return unusualList;
            }
            StaffResponse staffResponse = new StaffResponse();
            if (templateRedisClient.hasKey(getKey(key))){
                staffResponse = templateRedisClient.get(getKey(key));
            }
            list.sort(Comparator.comparing(item->item.getProjectTypeNum()));
            for (BaseProjectType projectType : list) {
                BaseProjectType baseProjectType1 = new BaseProjectType();
                baseProjectType1.setProjectTypeNum(projectType.getProjectTypeNum());
                baseProjectType1.setStoreId(storeId);
                BaseProjectType baseProjectType2 = dao.selectOne(baseProjectType1);
                if(null != baseProjectType2){
                    throw new SmsException(ResponseCode.MSG,"编码 {"+projectType.getProjectTypeNum()+"}已经存在") ;
                }
                //            projectType.setId(new SnowflakeUtil(new Random().nextInt(1023)).nextId());
                //批量上传避免数据量过大时new Random()重复导致生成的ID重复
                projectType.setId(SnowflakeUtil.getId());
                projectType.setStoreId(storeId);
                projectType.setStoreName(storeName);
                projectType.setFounderStaff(staffResponse.getStaffName());
                projectType.setFounderDatetime(new Date());
                if(null != projectType.getParentNum()){
                    BaseProjectType baseProjectType = new BaseProjectType();
                    baseProjectType.setProjectTypeNum(projectType.getParentNum());
                    baseProjectType.setStoreId(storeId);
                    BaseProjectType select = dao.selectOne(baseProjectType);
                    if(null != select){
                        projectType.setParentId(select.getId());
                    }
                }
                int insert = dao.insert(projectType);
                i=i+insert;
            }
            BaseProjectType baseProjectType = new BaseProjectType();
            baseProjectType.setStoreId(storeId);
            List<BaseProjectType> select = dao.select(baseProjectType);
            for (BaseProjectType projectType : select) {
                if(projectType.getParentNum()!=null&&projectType.getParentId()==null){
                    for (BaseProjectType type : select) {
                        if(projectType.getParentNum().equals(type.getProjectTypeNum())){
                            projectType.setParentId(type.getId());
                            dao.updateByPrimaryKeySelective(projectType);
                        }
                    }
                }
            }
            //i = dao.insertBatch(list);
            }catch (SmsException e){
            log.error("SsmProjectTypeServiceImpl.insertBatch:", e);
            throw e;
        }catch (Exception e){
            log.error("SsmProjectTypeServiceImpl.insertBatch:", e);
            throw new SmsException(ResponseCode.UNKNOWN_SYSTEM_EXCEPTION);
        }
        if (i != list.size()){
            throw new SmsException(ResponseCode.ENCRYPT_ERROR);
        }else {
            throw new SmsException(ResponseCode.OK);
        }
    }

    @Autowired
    BaseProjectTypeMapper mapper;
    @Override
    public List<Long> selectByEveryId(BaseProjectType baseProjectType) {
        return mapper.selectByEveryId(baseProjectType);
    }

    @Override
    public List<Long> selectByChild(BaseProjectType baseProjectType) {
        return mapper.selectByChild(baseProjectType);
    }
    public String getKey(String phone){
        String key = "";
        if (StringUtils.isNotBlank(phone)){
            key = Constant.staffKey + phone;
        }
        return key;
    }

    public void check(String projectTypeNum, String projectTypeName, Long storeId) throws SmsException {

        if (StringUtils.isNotBlank(projectTypeNum) || null != projectTypeNum){
            BaseProjectType projectType = new BaseProjectType();
            projectType.setProjectTypeNum(projectTypeNum);
            projectType.setState(1);
            projectType.setStoreId(storeId);
            List<BaseProjectType> projectTypeList = dao.select(projectType);
            if (projectTypeList.size() > 0){
                throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别编码");
            }
        }
        if (StringUtils.isNotBlank(projectTypeName) || null != projectTypeName){
            BaseProjectType projectType = new BaseProjectType();
            projectType.setProjectTypeName(projectTypeName);
            projectType.setState(1);
            projectType.setStoreId(storeId);
            List<BaseProjectType> projectTypeList = dao.select(projectType);
            if (projectTypeList.size() > 0){
                throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别名称");
            }
        }

    }

    public void check(String projectTypeNum, String projectTypeName, Long storeId,Long id) throws SmsException {
        BaseProjectType projectType = new BaseProjectType();
        if(id!=null){
            BaseProject baseProject = new BaseProject();
            baseProject.setProjectTypeId(id);
            int i = ssmProjectService.selectCount(baseProject);
            if(i>0){
                throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_SS);
            }
        }
        if (StringUtils.isNotBlank(projectTypeNum) || null != projectTypeNum){
            projectType.setProjectTypeNum(projectTypeNum);
            projectType.setState(1);
            projectType.setStoreId(storeId);

            List<BaseProjectType> projectTypeList = dao.select(projectType);
            if (projectTypeList.size() > 1){
                throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别编码");
            }else if (projectTypeList.size() > 0){
                if(projectTypeList.get(0).getId()!=id){
                    throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别编码");
                }
            }
        }
        if (StringUtils.isNotBlank(projectTypeName) || null != projectTypeName){
            projectType.setProjectTypeName(projectTypeName);
            projectType.setState(1);
            projectType.setStoreId(storeId);
            List<BaseProjectType> projectTypeList = dao.select(projectType);
            if (projectTypeList.size() > 1){
                throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别名称");
            }else if (projectTypeList.size() > 0){
                if(!projectTypeList.get(0).getProjectTypeName().equals(projectTypeName)){
                    throw new SmsException(ResponseCode.DATA_ALREADY_EXISTS_S,"类别名称");
                }
            }
        }
    }

    public List<BaseProjectType> check(List<BaseProjectType> list){
        List<BaseProjectType> unusualList = new ArrayList<>();
        Map<String, List<BaseProjectType>> map = list.stream().collect(Collectors.groupingBy(baseProjectType -> baseProjectType.getProjectTypeNum() + "-" + baseProjectType.getState()));
        for (String key : map.keySet()) {
            //编码数据重复
            if (map.get(key).size() > 1){
                unusualList.addAll(map.get(key));
                list.removeAll(map.get(key));
            }
        }
        Map<String, List<BaseProjectType>> map1 = list.stream().collect(Collectors.groupingBy(baseProjectType -> baseProjectType.getProjectTypeName()+ "-" + baseProjectType.getState()));
        for (String key : map1.keySet()) {
            //名称数据重复
            if (map1.get(key).size() > 1){
                unusualList.addAll(map1.get(key));
            }
        }
        return unusualList;
    }
}
