package com.zhongshu.card.server.core.service.devices.permiss;

import cn.hutool.json.JSONUtil;
import com.github.microservice.core.util.os.SystemUtil;
import com.github.microservice.models.device.DevicePerQuery;
import com.github.microservice.models.device.UserPerQuery;
import com.github.microservice.models.devicePermiss.DeviceAboutPermiss;
import com.github.microservice.models.devicePermiss.DeviceUsersInfo;
import com.github.microservice.models.devicePermiss.GateWayPermissModel;
import com.github.microservice.models.devicePermiss.ProjectUserPermiss;
import com.github.microservice.net.ResultContent;
import com.google.common.collect.Lists;
import com.zhongshu.card.client.model.school.CardInfoModel;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.client.type.school.CardState;
import com.zhongshu.card.server.core.dao.devices.DevicePermissDao;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dataConfig.CardSystemDefault;
import com.zhongshu.card.server.core.domain.devices.permiss.DevicePermiss;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.domain.org.UserAccount;
import com.zhongshu.card.server.core.domain.projectAbout.OrgUserFace;
import com.zhongshu.card.server.core.domain.school.CardInfo;
import com.zhongshu.card.server.core.service.projectAbout.CardInfoServiceImpl;
import com.zhongshu.card.server.core.service.projectAbout.OrgUserFaceService;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 设备权限 （绑定用户）管理
 *
 * @author TRX
 * @date 2024/10/11
 */
@Slf4j
@Service
public class DevicePermissIotService {

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private OrgUserFaceService orgUserFaceService;

    @Autowired
    private CardInfoServiceImpl cardInfoService;

    @Autowired
    private DevicePermissService devicePermissService;

    @Autowired
    private DevicePermissDao devicePermissDao;

    @Autowired
    private DevicePermissEventService devicePermissEventService;

    @Autowired
    private UserAccountServiceImpl userAccountService;

    //线程池
    private ExecutorService executorService = Executors.newFixedThreadPool(SystemUtil.getCpuCoreCount() * 2);

    @Autowired
    private void init(ApplicationContext applicationContext) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            executorService.shutdownNow();
        }));
    }

    /**
     * 组装设备权限变更的数据
     *
     * @param permisses DevicePermiss 设备用户绑定数据ID
     * @param mark      0: 删除   1：新增、修改   2：全量
     * @return
     */
    public ResultContent changeDeviceUser(List<DevicePermiss> permisses, int mark, String groupId) {
        if (ObjectUtils.isNotEmpty(permisses)) {
            executorService.execute(() -> {
                Map<String, List<DevicePermiss>> map = permisses.stream().collect(Collectors.groupingBy(DevicePermiss::getGateWayId));
                map.forEach((gateWayId, tempList) -> {
                    GateWayPermissModel gateWayPermissModel = new GateWayPermissModel();
                    gateWayPermissModel.setGateWayId(gateWayId);
                    gateWayPermissModel.setGroupId(groupId);
                    List<DeviceAboutPermiss> devices = tempList.stream().map(it -> {
                        DeviceAboutPermiss permiss = new DeviceAboutPermiss();
                        permiss.setDeviceId(it.getDeviceId());
                        permiss.addUser(it.getUserId());
                        //TODO
                        List<String> ids = new ArrayList<>();
                        for (int i = 0; i < 10000; i++) {
//                            ids.add(CommonUtil.UUID());
                        }
                        permiss.addUsers(ids);
                        permiss.setMark(mark);
                        return permiss;
                    }).collect(Collectors.toUnmodifiableList());
                    gateWayPermissModel.setDevices(devices);

                    // 下发设备数据
                    devicePermissEventService.requestDeviceBindData(gateWayPermissModel, tempList.get(0).getProjectOid());
                });
            });
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 下发用户信息数据
     *
     * @param permisses
     * @param mark
     * @return
     */
    public ResultContent changeUserInfo(List<DevicePermiss> permisses, int mark) {
        if (ObjectUtils.isNotEmpty(permisses)) {
            Map<String, List<DevicePermiss>> map = permisses.stream().collect(Collectors.groupingBy(DevicePermiss::getGateWayId));
            map.forEach((gateWayId, tempList) -> {
                DeviceUsersInfo deviceUsersInfo = new DeviceUsersInfo();
                deviceUsersInfo.setGateWayId(gateWayId);
                String projectOid = tempList.get(0).getProjectOid();
                // 用户数据 (去重)
                List<String> userIds = tempList.stream().map(it -> it.getUserId()).distinct().collect(Collectors.toList());
                List<ProjectUserPermiss> userPermiss = getUserPermiss(projectOid, userIds);

                deviceUsersInfo.setUsers(userPermiss);
                // 下发用户数据
                devicePermissEventService.requestDevicesUsersData(deviceUsersInfo, projectOid);
            });
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 查询设备的权限数据
     *
     * @param query
     * @return
     */
    public ResultContent queryDevicePermiss(DevicePerQuery query) {
        GateWayPermissModel permissModel = queryDevicePermissInfo(query);
        return ResultContent.buildSuccess(JSONUtil.toJsonStr(permissModel));
    }

    public GateWayPermissModel queryDevicePermissInfo(DevicePerQuery query) {
        GateWayPermissModel permissModel = getDeviceAboutUsers(query.getDeviceIds());
        permissModel.setSuccess();
        permissModel.setGateWayId(query.getGateWayId());
        return permissModel;
    }

    /**
     * 查询设备关联的用户信息（增加或修改）
     *
     * @param query
     * @return
     */
    public ResultContent getDeviceAboutUserInfos(DevicePerQuery query) {
        DeviceUsersInfo permissModel = queryDeviceAboutUsers(query);
        return ResultContent.buildSuccess(JSONUtil.toJsonStr(permissModel));
    }

    /**
     * @param query
     * @return
     */
    public DeviceUsersInfo queryDeviceAboutUsers(DevicePerQuery query) {
        DeviceUsersInfo permissModel = getDeviceAboutUserInfos(query.getDeviceIds());
        permissModel.setSuccess();
        permissModel.setGateWayId(query.getGateWayId());
        return permissModel;
    }

    /**
     * 查询项目下的用户权限信息 （根据userIds查询）
     *
     * @param query
     * @return
     */
    public ResultContent getDeviceAboutUserInfos(UserPerQuery query) {
        DeviceUsersInfo permissModel = new DeviceUsersInfo();
        String projectOid = "";
        String projectCode = query.getProjectCode();
        if (StringUtils.isNotEmpty(projectCode)) {
            Organization organization = organizationDao.findTopByCode(projectCode);
            if (ObjectUtils.isNotEmpty(organization)) {
                projectOid = organization.getOid();
            }
        }
        if (StringUtils.isNotEmpty(projectOid) && ObjectUtils.isNotEmpty(query.getUserIds())) {
            permissModel.setUsers(getUserPermiss(projectOid, query.getUserIds()));
        }
        permissModel.setSuccess();
        permissModel.setGateWayId(query.getGateWayId());
        return ResultContent.buildSuccess(JSONUtil.toJsonStr(permissModel));
    }

    public DeviceUsersInfo getDeviceAboutUserInfos(List<String> deviceIds) {
        DeviceUsersInfo deviceUsersInfo = new DeviceUsersInfo();
        if (ObjectUtils.isNotEmpty(deviceIds)) {
            List<DevicePermiss> list = devicePermissDao.findByDeviceIdInAndDataState(deviceIds, DataState.Enable);
            if (ObjectUtils.isNotEmpty(list)) {
                // 用户userId集合
                List<String> _userIds = list.stream().map(it -> it.getUserId()).collect(Collectors.toUnmodifiableList());
                List<ProjectUserPermiss> userPermiss = getUserPermiss(list.get(0).getProjectOid(), _userIds.stream().distinct().collect(Collectors.toList()));
                deviceUsersInfo.setUsers(userPermiss);
            }
        }
        return deviceUsersInfo;
    }

    /**
     * 组装用户在项目下的数据 mark：默认是1 ，编辑、增加 (用户名称、头像、卡片)
     *
     * @param projectOid 项目oid
     * @param userIds    用户userId集合
     * @return
     */
    public List<ProjectUserPermiss> getUserPermiss(String projectOid, List<String> userIds) {
        if (StringUtils.isNotEmpty(projectOid) && ObjectUtils.isNotEmpty(userIds)) {
            // 用户信息
            List<UserAccount> userAccounts = userAccountService.getUserAccounts(userIds);
            Map<String, UserAccount> userMap = userAccounts.stream().collect(Collectors.toMap(it -> it.getUserId(), it -> it, (v1, v2) -> v1));

            // 人脸信息
            List<OrgUserFace> userFaces = orgUserFaceService.getUserFaces(projectOid, userIds);
            Map<String, OrgUserFace> faceMap = userFaces.stream().collect(Collectors.toMap(it -> it.getUserId(), it -> it, (v1, v2) -> v1));

            // 用户的卡片信息
            List<CardInfo> cardInfos = cardInfoService.getProjectCards(projectOid, userIds);
            Map<String, List<CardInfo>> cardMap = cardInfos.stream().collect(Collectors.groupingBy(CardInfo::getUserId));

            Map<String, ProjectUserPermiss> map = new HashMap<>();
            for (String userId : userIds) {
                ProjectUserPermiss permiss = null;
                if (map.containsKey(userId)) {
                    permiss = map.get(userId);
                } else {
                    permiss = new ProjectUserPermiss();
                }
                permiss.setUid(userId);
                UserAccount userAccount = userMap.get(userId);
                if (ObjectUtils.isNotEmpty(userAccount)) {
                    permiss.setUn(userAccount.getName());
                }
                OrgUserFace orgUserFace = faceMap.get(userId);
                if (ObjectUtils.isNotEmpty(orgUserFace)) {
                    permiss.setFi(orgUserFace.getImg());
                }
                List<CardInfo> cardInfoList = cardMap.get(userId);
                if (ObjectUtils.isNotEmpty(cardInfoList)) {
                    permiss.setCNos(cardInfoList.stream().map(it -> it.getCode()).collect(Collectors.toList()));
                } else {
                    permiss.setCNos(List.of("unKnow"));
                }
                map.put(userId, permiss);
            }
            return List.copyOf(map.values());
        }
        return Lists.newArrayList();
    }

    /**
     * 得到设备关联的用户 （用户数据发生了变化，为什么要在权限表来查询数据诶？
     * 因为要来查询用户关联的设备->设备关联的网关，才能知道往那个网关推送数据
     *
     * @param deviceIds
     * @return
     */
    public GateWayPermissModel getDeviceAboutUsers(List<String> deviceIds) {
        GateWayPermissModel gateWayPermissModel = new GateWayPermissModel();
        if (ObjectUtils.isNotEmpty(deviceIds)) {
            List<DevicePermiss> list = devicePermissDao.findByDeviceIdInAndDataState(deviceIds, DataState.Enable);
            if (ObjectUtils.isNotEmpty(list)) {
                List<DeviceAboutPermiss> devices = new ArrayList<DeviceAboutPermiss>();
                // 以设备分组
                Map<String, List<DevicePermiss>> groupedItems = list.stream().collect(Collectors.groupingBy(DevicePermiss::getDeviceId));
                groupedItems.forEach((deviceId, itemsInCategory) -> {
                    DeviceAboutPermiss aboutPermiss = new DeviceAboutPermiss();
                    aboutPermiss.setDeviceId(deviceId);
                    List<String> _userIds = itemsInCategory.stream().map(it -> it.getUserId()).collect(Collectors.toUnmodifiableList());
                    aboutPermiss.setUserIds(_userIds.stream().distinct().collect(Collectors.toUnmodifiableList()));
                    devices.add(aboutPermiss);
                });
                gateWayPermissModel.setDevices(devices);
            }
        }
        return gateWayPermissModel;
    }

    /**
     * 组装用户信息 权限数据
     *
     * @param devicePermiss
     * @return
     */
    public ProjectUserPermiss toModel(DevicePermiss devicePermiss) {
        ProjectUserPermiss userPermiss = null;
        if (ObjectUtils.isNotEmpty(devicePermiss)) {
            userPermiss = new ProjectUserPermiss();
            String userId = devicePermiss.getUserId();
            String projectOid = devicePermiss.getProjectOid();
            UserAccount account = devicePermiss.getUserAccount();
            userPermiss.setUid(userId);
            if (ObjectUtils.isNotEmpty(account)) {
                userPermiss.setUn(account.getName());
            }

            // 查询用户的头像
            OrgUserFace orgUserFace = orgUserFaceService.getUserFace(userId, projectOid);
            if (ObjectUtils.isNotEmpty(orgUserFace)) {
                userPermiss.setFi(orgUserFace.getImg());
            } else {
                // 默认头像
                userPermiss.setFi(CardSystemDefault.defaultPermissFaceUrl);
            }

            // 查询用户的卡片
            List<CardInfoModel> list = cardInfoService.getUserOrgAllCard(userId, projectOid);
            List<String> cardNos = new ArrayList<>();
            if (ObjectUtils.isNotEmpty(list)) {
                cardNos = list.stream().filter(it -> it.getCardState() == CardState.Enable).map(it -> it.getCode()).collect(Collectors.toUnmodifiableList());
            }
            userPermiss.setCNos(cardNos);
        }
        return userPermiss;
    }
}
