package com.cool.store.service.impl;

import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.HyInspectionSettingDAO;
import com.cool.store.dao.HyInspectionSettingMappingDAO;
import com.cool.store.dao.HyOpenAreaInfoDAO;
import com.cool.store.dto.inspection.setting.AddInspectionSettingDTO;
import com.cool.store.dto.inspection.setting.CheckInspectionSettingDTO;
import com.cool.store.dto.inspection.setting.UpdateInspectionSettingDTO;
import com.cool.store.entity.HyInspectionSettingDO;
import com.cool.store.entity.HyInspectionSettingMappingDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.InspectionSettingService;
import com.cool.store.vo.inspection.setting.InspectionSettingCheckVO;
import com.cool.store.vo.inspection.setting.InspectionSettingDetailVO;
import com.cool.store.vo.inspection.setting.InspectionSettingPageVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangchenbiao
 * @FileName: InspectionSettingServiceImpl
 * @Description:
 * @date 2023-07-18 16:06
 */
@Service
public class InspectionSettingServiceImpl implements InspectionSettingService {

    @Resource
    private HyInspectionSettingDAO hyInspectionSettingDAO;
    @Resource
    private HyInspectionSettingMappingDAO hyInspectionSettingMappingDAO;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private HyOpenAreaInfoDAO hyOpenAreaInfoDAO;

    @Override
    public PageInfo<InspectionSettingPageVO> getInspectionSettingPage(Integer pageNum, Integer pageSize) {
        Page<HyInspectionSettingDO> inspectionSettingPage = hyInspectionSettingDAO.getInspectionSettingPage(pageNum, pageSize);
        Map<String, String> userNameMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(inspectionSettingPage)){
            List<String> userIds = inspectionSettingPage.stream().map(HyInspectionSettingDO::getInspectionUserId).distinct().collect(Collectors.toList());
            List<String> updateUserIds = inspectionSettingPage.stream().map(HyInspectionSettingDO::getUpdateUserId).distinct().collect(Collectors.toList());
            userIds.addAll(updateUserIds);
            userNameMap = enterpriseUserDAO.getUserNameMap(userIds);
        }
        List<InspectionSettingPageVO> resultList = InspectionSettingPageVO.convert(inspectionSettingPage, userNameMap);
        PageInfo resultPage = new PageInfo(inspectionSettingPage);
        resultPage.setList(resultList);
        return resultPage;
    }

    @Override
    public InspectionSettingDetailVO getInspectionSettingDetail(Long inspectionSettingId) {
        HyInspectionSettingDO inspectionSetting = hyInspectionSettingDAO.getInspectionSettingDetail(inspectionSettingId);
        if(Objects.isNull(inspectionSetting)){
            return null;
        }
        List<Long> openAreaMappingIds = hyInspectionSettingMappingDAO.getOpenAreaMappingIds(inspectionSettingId);
        String inspectionUsername = enterpriseUserDAO.getUserName(inspectionSetting.getInspectionUserId());
        return InspectionSettingDetailVO.convertVO(inspectionSetting, inspectionUsername, openAreaMappingIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addInspectionSetting(String userId, AddInspectionSettingDTO param) {
        List<HyInspectionSettingDO> inspectionUserSetting = hyInspectionSettingDAO.getHyInspectionSettingByUserId(param.getInspectionUserId(), null);
        if(CollectionUtils.isNotEmpty(inspectionUserSetting)){
            throw new ServiceException(ErrorCodeEnum.INSPECTION_USER_OCCUPY);
        }
        List<Long> openAreaMappingIds = hyOpenAreaInfoDAO.filterLeafNode(param.getOpenAreaMappingIds());
        if(CollectionUtils.isEmpty(openAreaMappingIds)){
            throw new ServiceException(ErrorCodeEnum.OPEN_AREA_NULL);
        }
        HyInspectionSettingDO inspectionSetting = new HyInspectionSettingDO();
        inspectionSetting.setInspectionUserId(param.getInspectionUserId());
        inspectionSetting.setZoneName(param.getZoneName());
        inspectionSetting.setCreateUserId(userId);
        inspectionSetting.setCreateTime(new Date());
        inspectionSetting.setUpdateUserId(userId);
        inspectionSetting.setUpdateTime(new Date());
        Long inspectionSettingId = hyInspectionSettingDAO.addInspectionSetting(inspectionSetting);
        hyInspectionSettingMappingDAO.addInspectionSettingMapping(inspectionSettingId, openAreaMappingIds);
        return inspectionSettingId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateInspectionSetting(String userId, UpdateInspectionSettingDTO param) {
        List<HyInspectionSettingDO> inspectionUserSetting = hyInspectionSettingDAO.getHyInspectionSettingByUserId(param.getInspectionUserId(), param.getInspectionSettingId());
        if(CollectionUtils.isNotEmpty(inspectionUserSetting)){
            throw new ServiceException(ErrorCodeEnum.INSPECTION_USER_OCCUPY);
        }
        List<Long> openAreaMappingIds = hyOpenAreaInfoDAO.filterLeafNode(param.getOpenAreaMappingIds());
        if(CollectionUtils.isEmpty(openAreaMappingIds)){
            throw new ServiceException(ErrorCodeEnum.OPEN_AREA_NULL);
        }
        HyInspectionSettingDO inspectionSetting = new HyInspectionSettingDO();
        inspectionSetting.setId(param.getInspectionSettingId());
        inspectionSetting.setInspectionUserId(param.getInspectionUserId());
        inspectionSetting.setZoneName(param.getZoneName());
        inspectionSetting.setUpdateUserId(userId);
        inspectionSetting.setUpdateTime(new Date());
        hyInspectionSettingDAO.updateInspectionSetting(inspectionSetting);
        return hyInspectionSettingMappingDAO.updateInspectionSettingMapping(param.getInspectionSettingId(), openAreaMappingIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteInspectionSetting(String userId, Long inspectionSettingId) {
        HyInspectionSettingDO inspectionSetting = new HyInspectionSettingDO();
        inspectionSetting.setId(inspectionSettingId);
        inspectionSetting.setUpdateUserId(userId);
        inspectionSetting.setUpdateTime(new Date());
        inspectionSetting.setDeleted(Boolean.TRUE);
        hyInspectionSettingDAO.updateInspectionSetting(inspectionSetting);
        hyInspectionSettingMappingDAO.deleteInspectionSettingMapping(inspectionSettingId);
        return hyInspectionSettingDAO.updateInspectionSetting(inspectionSetting);
    }

    @Override
    public List<InspectionSettingCheckVO> checkInspectionSetting(CheckInspectionSettingDTO param) {
        if(CollectionUtils.isEmpty(param.getOpenAreaMappingIds())){
            return Lists.newArrayList();
        }
        List<HyInspectionSettingMappingDO> conflictInspectionSetting = hyInspectionSettingMappingDAO.getConflictInspectionSetting(param.getInspectionSettingId(), param.getOpenAreaMappingIds());
        List<Long> inspectionSettingIds = ListUtils.emptyIfNull(conflictInspectionSetting).stream().map(HyInspectionSettingMappingDO::getInspectionSettingId).distinct().collect(Collectors.toList());
        List<HyInspectionSettingDO> inspectionSettingList = hyInspectionSettingDAO.getHyInspectionSettingByIds(inspectionSettingIds);
        List<String> inspectionUserIds = ListUtils.emptyIfNull(inspectionSettingList).stream().map(HyInspectionSettingDO::getInspectionUserId).distinct().collect(Collectors.toList());
        List<Long> openAreaMappingIds = ListUtils.emptyIfNull(conflictInspectionSetting).stream().map(HyInspectionSettingMappingDO::getOpenAreaMappingId).distinct().collect(Collectors.toList());
        Map<Long, String> areaNameMap = hyOpenAreaInfoDAO.getNameMapByIds(openAreaMappingIds);
        Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(inspectionUserIds);
        return InspectionSettingCheckVO.convertVO(conflictInspectionSetting, inspectionSettingList, userNameMap, areaNameMap);
    }

    @Override
    public List<String> getBingUser() {
        return hyInspectionSettingDAO.getInspectionUserIds();
    }
}
