package com.zhongshu.card.server.core.service.org;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.net.ResultMessage;
import com.zhongshu.card.client.model.base.IDsParam;
import com.zhongshu.card.client.model.org.userGroup.*;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dao.org.OrganizationUserDao;
import com.zhongshu.card.server.core.dao.org.UserGroupDao;
import com.zhongshu.card.server.core.dao.org.UserGroupToUserDao;
import com.zhongshu.card.server.core.domain.org.*;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.devices.permiss.DevicePermissEventService;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import com.zhongshu.card.server.core.util.BeanUtils;
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.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户分组
 *
 * @author TRX
 * @date 2024/12/19
 */
@Slf4j
@Service
public class UserGroupService extends SuperService {

    @Autowired
    private UserGroupDao userGroupDao;

    @Autowired
    private UserGroupToUserDao userGroupToUserDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private UserAccountServiceImpl userAccountService;

    @Autowired
    private OrganizationUserDao organizationUserDao;

    @Autowired
    private DevicePermissEventService devicePermissEventService;

    public ResultContent saveInfo(UserGroupParam param) {
        Assert.hasText(param.getProjectOid(), "projectOid不能为空");

        UserGroup entity = null;
        if (StringUtils.isNotEmpty(param.getId())) {
            entity = userGroupDao.findTopById(param.getId());
            if (ObjectUtils.isEmpty(entity)) {
                return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, param.getId()));
            }
            initUpdateEntity(entity);
        } else {
            entity = new UserGroup();
            initEntityNoCheckOid(entity);
        }
        BeanUtils.copyProperties(param, entity);
        userGroupDao.save(entity);

        // 权限变化
        return ResultContent.buildSuccess();
    }

    public ResultContent<Page<UserGroupModel>> page(UserGroupSearch param, Pageable pageable) {
        String projectOid = param.getProjectOid();
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail("projectOid不存在");
        }
        Page<UserGroup> page = userGroupDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    /**
     * 删除设备分组
     *
     * @param id
     * @return
     */
    public ResultContent deleteInfo(String id) {
        UserGroup entity = userGroupDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        List<String> userIds = new ArrayList<>();
        List<UserGroupToUser> list = userGroupToUserDao.findByUserGroup(entity);
        if (ObjectUtils.isNotEmpty(list)) {
            userIds = list.stream().map(it -> it.getUserId()).collect(Collectors.toList());
        }
        userGroupDao.delete(entity);
        userGroupToUserDao.deleteByUserGroup(entity);

        // 权限变化
        devicePermissEventService.sendUserInfoChangeEvent(userIds, entity.getProjectOid(), "deleteInfo userGroup");
        return ResultContent.buildSuccess();
    }

    public ResultContent<UserGroupModel> getDetailInfo(String id) {
        UserGroup entity = userGroupDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        return ResultContent.buildSuccess(toModel(entity));
    }

    public ResultContent changeState(String id, DataState state) {
        UserGroup entity = userGroupDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        entity.setState(state);
        userGroupDao.save(entity);

        List<String> userIds = new ArrayList<>();
        List<UserGroupToUser> list = userGroupToUserDao.findByUserGroup(entity);
        if (ObjectUtils.isNotEmpty(list)) {
            userIds = list.stream().map(it -> it.getUserId()).collect(Collectors.toList());
        }
        devicePermissEventService.sendUserInfoChangeEvent(userIds, entity.getProjectOid(), "changeState userGroup");
        return ResultContent.buildSuccess();
    }

    //-----------------------------分组关联的用户信息 start--------------------

    public ResultContent groupBindUser(UserGroupToUserAddParam param) {
        UserGroup userGroup = userGroupDao.findTopById(param.getGroupId());
        if (ObjectUtils.isEmpty(userGroup)) {
            return ResultContent.buildFail("分组不存在");
        }
        if (ObjectUtils.isEmpty(param.getOrgUserId())) {
            return ResultContent.buildFail("用户信息为空");
        }
        List<OrganizationUser> list = organizationUserDao.findByIdIn(param.getOrgUserId());
        if (ObjectUtils.isNotEmpty(list)) {
            List<String> userIds = new ArrayList<>();
            List<UserGroupToUser> saveList = new ArrayList<>();
            for (OrganizationUser organizationUser : list) {
                UserGroupToUser userGroupToUser = userGroupToUserDao.findTopByUserGroupAndOrganizationUser(userGroup, organizationUser);
                if (ObjectUtils.isEmpty(userGroupToUser)) {
                    userGroupToUser = new UserGroupToUser();
                    userGroupToUser.setUserGroup(userGroup);
                    userGroupToUser.setUserGroupId(userGroup.getId());
                    userGroupToUser.setOrganizationUser(organizationUser);

                    userGroupToUser.setProjectOid(userGroup.getProjectOid());
                    userGroupToUser.setOrgDataId(organizationUser.getId());
                    UserAccount userAccount = organizationUser.getUser();
                    userGroupToUser.setUserName(userAccount.getName());
                    userGroupToUser.setUserId(userAccount.getUserId());
                    userIds.add(userAccount.getUserId());

                    initEntity(userGroupToUser);
                    saveList.add(userGroupToUser);
                }
            }
            if (ObjectUtils.isNotEmpty(saveList)) {
                userGroupToUserDao.saveAll(saveList);
                initGroupNumber(userGroup);
                devicePermissEventService.sendUserInfoChangeEvent(userIds, userGroup.getProjectOid(), "groupBindUser userGroup");
            }
        }
        return ResultContent.buildSuccess();
    }

    public ResultContent deleteGroupUserInfo(String id) {
        UserGroupToUser entity = userGroupToUserDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        userGroupToUserDao.delete(entity);
        initGroupNumber(entity.getUserGroup());
        devicePermissEventService.sendUserInfoChangeEvent(entity.getUserId(), entity.getProjectOid(), "deleteGroupUserInfo userGroup");
        return ResultContent.buildSuccess();
    }

    public ResultContent deleteGroupUsersInfo(IDsParam param) {
        if (ObjectUtils.isEmpty(param.getIds())) {
            return ResultContent.buildFail("ids不能为空");
        }
        List<UserGroupToUser> list = userGroupToUserDao.findByIdIn(param.getIds());
        if (ObjectUtils.isEmpty(list)) {
            return ResultContent.buildFail("数据不存在");
        }
        userGroupToUserDao.deleteAllById(param.getIds());
        initGroupNumber(list.get(0).getUserGroup());

        List<String> userIds = list.stream().map(it -> it.getUserId()).collect(Collectors.toList());
        devicePermissEventService.sendUserInfoChangeEvent(userIds, list.get(0).getProjectOid(), "deleteGroupUsersInfo userGroup");
        return ResultContent.buildSuccess();
    }

    public void initGroupNumber(UserGroup userGroup) {
        if (ObjectUtils.isNotEmpty(userGroup)) {
            long number = userGroupToUserDao.countByUserGroup(userGroup);
            userGroup.setNumber(number);
            userGroupDao.save(userGroup);
        }
    }

    /**
     * 查询分组的用户信息分页列表
     *
     * @param param
     * @param pageable
     * @return
     */
    public ResultContent<Page<UserGroupToUserModel>> pageGroupUsers(UserGroupToUserSearch param, Pageable pageable) {
        String projectOid = param.getProjectOid();
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail("projectOid不存在");
        }
        if (StringUtils.isEmpty(param.getGroupId())) {
            return ResultContent.buildFail("groupId不能为空");
        }

        Page<UserGroupToUser> page = userGroupToUserDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toUserModel));
    }

    //-----------------------------分组关联的用户信息 end----------------------

    private UserGroupModel toModel(UserGroup entity) {
        UserGroupModel model = new UserGroupModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

    public UserGroupToUserModel toUserModel(UserGroupToUser entity) {
        UserGroupToUserModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new UserGroupToUserModel();
            model.setId(entity.getId());

            model.setUser(userAccountService.toOrgUserModel(entity.getOrganizationUser()));
        }
        return model;
    }

}
