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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yuchen.saas.park.api.commons.IdHierarchyTree;
import com.yuchen.saas.park.api.commons.IdTree;
import com.yuchen.saas.park.api.commons.PageWrapper;
import com.yuchen.saas.park.api.entity.door.DoorDeviceGroup;
import com.yuchen.saas.park.api.entity.door.DoorDeviceGroupItem;
import com.yuchen.saas.park.service.mapper.domain.adapter.DoorAccessControlTemplateIdNoRo;
import com.yuchen.saas.park.service.mapper.domain.config.details.DoorAccessControlCondition;
import com.yuchen.saas.park.service.mapper.domain.config.details.DoorAccessControlRO;
import com.yuchen.saas.park.service.mapper.door.adapter.AdapterRepository;
import com.yuchen.saas.park.service.service.door.DoorDeviceGroupItemService;
import com.yuchen.saas.park.service.service.door.DoorDeviceGroupService;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.StringUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.Positive;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.*;

@Component
@RequiredArgsConstructor
public class AdapterComponentImpl implements AdapterComponent {
    private final AdapterRepository adapterRepository;

    private final DoorDeviceGroupService doorDeviceGroupService;

    private final DoorDeviceGroupItemService doorDeviceGroupItemService;

    @Override
    public Map<@Positive Long, Set<@Positive Long>> listUserIdByDepartmentIds(Set<@Positive Long> ids) {
        if (ids.isEmpty()) {
            return Map.of();
        }

        val list = adapterRepository.listUserIdByDepartmentIds(ids);

        if (CollectionUtils.isEmpty(list)) {
            return Map.of();
        }

        return list.stream().collect(groupingBy(IdTree::getParentId, mapping(IdTree::getId, toSet())));
    }

    @Override
    public Map<@Positive Long, Set<@Positive Long>> listDepartmentIdsByDepartmentIdsRecursive(Set<@Positive Long> ids) {
        if (ids.isEmpty()) {
            return Map.of();
        }

        val list = adapterRepository.listAllDepartmentId();
        if (CollectionUtils.isEmpty(list)) {
            return Map.of();
        }

        val tree = IdHierarchyTree.from(list);

        return ids.stream().collect(toMap(o -> o, o -> IdHierarchyTree.listIdRecursiveById(tree, o)));
    }

    @Override
    public Map<@Positive Long, Set<@Positive Long>> listUserIdByUserGroupIds(Set<@Positive Long> ids) {
        if (ids.isEmpty()) {
            return Map.of();
        }

        val list = adapterRepository.listUserIdByUserGroupIds(ids);
        if (CollectionUtils.isEmpty(list)) {
            return Map.of();
        }

        return list.stream().collect(groupingBy(IdTree::getParentId, mapping(IdTree::getId, toSet())));
    }

    @Override
    public Map<@Positive Long, Set<@Positive Long>> listDoorAccessControlIdByGroupIds(Set<@Positive Long> ids) {
        if (ids.isEmpty()) {
            return Map.of();
        }

        val list = adapterRepository.listDoorAccessControlIdByGroupIds(ids);
        if (CollectionUtils.isEmpty(list)) {
            return Map.of();
        }

        return list.stream().collect(groupingBy(IdTree::getParentId, mapping(IdTree::getId, toSet())));
    }

    @Override
    public IPage<DoorAccessControlRO> pageDoorAccessControl(PageWrapper<DoorAccessControlCondition> o) {
        IPage<DoorAccessControlRO> doorAccessControlROIPage = adapterRepository.pageDoorAccessControl(o.getPage(), ofNullable(o.getT()).orElse(new DoorAccessControlCondition()));
        //组装门禁分组数据
        if(Func.isNotEmpty(doorAccessControlROIPage)){
            List<DoorAccessControlRO> list = doorAccessControlROIPage.getRecords();
            for (DoorAccessControlRO doorAccessControlRO : list) {
                long id = doorAccessControlRO.getId();
                List<DoorDeviceGroupItem> itemList = doorDeviceGroupItemService.list(new LambdaQueryWrapper<DoorDeviceGroupItem>().eq(DoorDeviceGroupItem::getDevicePointId, id));
                if (Func.isNotEmpty(itemList)) {
                    List<Long> idList = itemList.stream().map(DoorDeviceGroupItem::getDeviceGroupId).collect(toList());
                    List<DoorDeviceGroup> groupList = doorDeviceGroupService.listByIds(idList);
                    if(Func.isNotEmpty(groupList)){
                        List<String> names = groupList.stream().map(DoorDeviceGroup::getGroupName).collect(toList());
                        String joinNames = StringUtil.join(names, ",");
                        doorAccessControlRO.setGroupNames(joinNames);
                    }
                }
            }
        }
        return doorAccessControlROIPage;
    }

    @Override
    public Map<@Positive Long, @Positive Integer> listAllDoorAccessControlTemplateIdNo() {
        val list = adapterRepository.listAllDoorAccessControlTemplateIdNo();

        if (CollectionUtils.isEmpty(list)) {
            return Map.of();
        }

        return list.stream().collect(toMap(DoorAccessControlTemplateIdNoRo::getId, DoorAccessControlTemplateIdNoRo::getNo));
    }
}
