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

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.devices.deviceGroup.*;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.server.core.dao.devices.DeviceGroupDao;
import com.zhongshu.card.server.core.dao.devices.DeviceGroupToDeviceDao;
import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.domain.devices.DeviceGroup;
import com.zhongshu.card.server.core.domain.devices.DeviceGroupToDevice;
import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
import com.zhongshu.card.server.core.domain.org.Organization;
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.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 DeviceGroupService extends SuperService {

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private DeviceGroupDao deviceGroupDao;

    @Autowired
    private DeviceGroupToDeviceDao deviceGroupToDeviceDao;

    @Autowired
    private DeviceInfoDao deviceInfoDao;

    @Autowired
    private DeviceInfoServiceImpl deviceInfoService;

    @Autowired
    private DevicePermissEventService devicePermissEventService;

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

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

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

    /**
     * 删除设备分组
     *
     * @param id
     * @return
     */
    public ResultContent deleteInfo(String id) {
        DeviceGroup entity = deviceGroupDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        List<DeviceGroupToDevice> list = deviceGroupToDeviceDao.findByDeviceGroup(entity);
        deviceGroupDao.delete(entity);
        deviceGroupToDeviceDao.deleteByDeviceGroup(entity);

        if (ObjectUtils.isNotEmpty(list)) {
            List<String> deviceIds = list.stream().map(it -> it.getDeviceId()).collect(Collectors.toUnmodifiableList());
            devicePermissEventService.sendDeviceChangeEvent(deviceIds, entity.getProjectOid(), "DeviceGroupService deleteInfo ");
        }
        return ResultContent.buildSuccess();
    }

    public ResultContent<DeviceGroupModel> getDetailInfo(String id) {
        DeviceGroup entity = deviceGroupDao.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) {
        DeviceGroup entity = deviceGroupDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        entity.setState(state);
        deviceGroupDao.save(entity);

        // 发起设备权限发生变化
        List<DeviceGroupToDevice> list = deviceGroupToDeviceDao.findByDeviceGroup(entity);
        if (ObjectUtils.isNotEmpty(list)) {
            List<String> deviceIds = list.stream().map(it -> it.getDeviceId()).collect(Collectors.toUnmodifiableList());
            devicePermissEventService.sendDeviceChangeEvent(deviceIds, entity.getProjectOid(), "DeviceGroupService deleteInfo ");
        }
        return ResultContent.buildSuccess();
    }

    //-----------------------------分组关联的设备信息 start--------------------

    public ResultContent groupBindDevices(DeviceGroupToDeviceAddParam param) {
        DeviceGroup deviceGroup = deviceGroupDao.findTopById(param.getGroupId());
        if (ObjectUtils.isEmpty(deviceGroup)) {
            return ResultContent.buildFail("分组不存在");
        }
        if (ObjectUtils.isEmpty(param.getDeviceIds())) {
            return ResultContent.buildFail("设备信息为空");
        }

        List<DeviceInfo> list = deviceInfoDao.findByDeviceIdIn(param.getDeviceIds());
        if (ObjectUtils.isEmpty(list)) {
            return ResultContent.buildFail("未查询到设备");
        }
        if (ObjectUtils.isNotEmpty(list)) {
            List<DeviceGroupToDevice> saveList = new ArrayList<>();
            for (DeviceInfo deviceInfo : list) {
                DeviceGroupToDevice deviceGroupToDevice = deviceGroupToDeviceDao.findTopByDeviceGroupAndDeviceInfo(deviceGroup, deviceInfo);
                if (ObjectUtils.isEmpty(deviceGroupToDevice)) {
                    deviceGroupToDevice = new DeviceGroupToDevice();
                    deviceGroupToDevice.setDeviceGroup(deviceGroup);
                    deviceGroupToDevice.setDeviceInfo(deviceInfo);

                    deviceGroupToDevice.setProjectOid(deviceGroup.getProjectOid());
                    deviceGroupToDevice.setDeviceId(deviceInfo.getDeviceId());
                    deviceGroupToDevice.setDeviceName(deviceInfo.getDeviceName());

                    initEntity(deviceGroupToDevice);
                    saveList.add(deviceGroupToDevice);
                }
            }
            if (ObjectUtils.isNotEmpty(saveList)) {
                deviceGroupToDeviceDao.saveAll(saveList);
                initGroupNumber(deviceGroup);

                devicePermissEventService.sendDeviceChangeEvent(param.getDeviceIds(), deviceGroup.getProjectOid(), "DeviceGroupService groupBindDevices ");
            }
        }
        return ResultContent.buildSuccess();
    }

    public ResultContent deleteGroupDeviceInfo(String id) {
        DeviceGroupToDevice entity = deviceGroupToDeviceDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        deviceGroupToDeviceDao.delete(entity);
        initGroupNumber(entity.getDeviceGroup());

        devicePermissEventService.sendDeviceChangeEvent(entity.getDeviceId(), entity.getProjectOid(), "DeviceGroupService deleteGroupDeviceInfo ");
        return ResultContent.buildSuccess();
    }

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

    public void initGroupNumber(DeviceGroup deviceGroup) {
        if (ObjectUtils.isNotEmpty(deviceGroup)) {
            long number = deviceGroupToDeviceDao.countByDeviceGroup(deviceGroup);
            deviceGroup.setNumber(number);
            deviceGroupDao.save(deviceGroup);
        }
    }

    public ResultContent<Page<DeviceGroupToDeviceModel>> pageGroupDevices(DeviceGroupToDeviceSearch param, Pageable pageable) {
        String projectOid = param.getProjectOid();
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail("projectOid不存在");
        }
        Page<DeviceGroupToDevice> page = deviceGroupToDeviceDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toDeviceModel));
    }

    //-----------------------------分组关联的设备信息 end----------------------

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

    public DeviceGroupToDeviceModel toDeviceModel(DeviceGroupToDevice entity) {
        DeviceGroupToDeviceModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new DeviceGroupToDeviceModel();
            model.setId(entity.getId());

            model.setDeviceInfoModel(deviceInfoService.toModel(entity.getDeviceInfo()));
        }
        return model;
    }

}
