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

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.net.ResultMessage;
import com.google.common.collect.Lists;
import com.zhongshu.card.client.model.base.IDsParam;
import com.zhongshu.card.client.model.devices.deviceProduct.DeviceProductBindDeviceBind;
import com.zhongshu.card.client.model.devices.deviceProduct.DeviceProductBindDeviceModel;
import com.zhongshu.card.client.model.devices.deviceProduct.DeviceProductBindDeviceSearch;
import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
import com.zhongshu.card.server.core.dao.devices.DeviceProductBindDeviceDao;
import com.zhongshu.card.server.core.dao.devices.DeviceProductDao;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
import com.zhongshu.card.server.core.domain.devices.DeviceProduct;
import com.zhongshu.card.server.core.domain.devices.DeviceProductBindDevice;
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.DeviceInfoServiceImpl;
import com.zhongshu.card.server.core.util.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
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 java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author TRX
 * @date 2025/1/8
 */
@Slf4j
@Service
public class DeviceProductBindDeviceService extends SuperService {

    @Autowired
    private DeviceProductDao deviceProductDao;

    @Autowired
    private DeviceProductBindDeviceDao deviceProductBindDeviceDao;

    @Autowired
    private DeviceInfoDao deviceInfoDao;

    @Autowired
    private DeviceProductService deviceProductService;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private DeviceInfoServiceImpl deviceInfoService;

    /**
     * 产品绑定设备信息
     *
     * @param param
     * @return
     */
    public ResultContent bindDevices(DeviceProductBindDeviceBind param) {
        DeviceProduct deviceProduct = deviceProductDao.findTopById(param.getDeviceProductId());
        if (ObjectUtils.isEmpty(deviceProduct)) {
            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<DeviceProductBindDevice> saveList = new ArrayList<>();
            for (DeviceInfo deviceInfo : list) {
                // 检查是否已绑定
                DeviceProductBindDevice old = deviceProductBindDeviceDao.findTopByDeviceIdOrderByCreateTimeDesc(deviceInfo.getDeviceId());
                DeviceProductBindDevice deviceProductBindDevice = deviceProductBindDeviceDao.findTopByDeviceProductAndDeviceId(deviceProduct, deviceInfo.getDeviceId());
                if (ObjectUtils.isNotEmpty(old) && (ObjectUtils.isEmpty(deviceProductBindDevice))
                        || !deviceProductBindDevice.getId().equals(old.getId())) {
                    // 已绑定，将不能继续绑定
                    continue;
                }

                if (ObjectUtils.isEmpty(deviceProductBindDevice)) {
                    deviceProductBindDevice = new DeviceProductBindDevice();
                    deviceProductBindDevice.setDeviceProduct(deviceProduct);
                    deviceProductBindDevice.setDeviceProductId(deviceProduct.getId());
                    deviceProductBindDevice.setDeviceInfo(deviceInfo);

                    deviceProductBindDevice.setProjectOid(deviceProduct.getProjectOid());
                    deviceProductBindDevice.setDeviceId(deviceInfo.getDeviceId());
                    initEntity(deviceProductBindDevice);
                } else {
                    deviceProductBindDevice.setDeviceName(deviceInfo.getDeviceName());
                    deviceProductBindDevice.setDeviceType(deviceInfo.getDeviceType());
                    deviceProductBindDevice.setSpecType(deviceInfo.getSpecType());
                }
                saveList.add(deviceProductBindDevice);
            }
            if (ObjectUtils.isNotEmpty(saveList)) {
                deviceProductBindDeviceDao.saveAll(saveList);
                deviceProductService.updateNumber(deviceProduct);
            }
        }
        return ResultContent.buildSuccess();
    }

    public ResultContent deleteDeviceInfo(String id) {
        DeviceProductBindDevice entity = deviceProductBindDeviceDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        deviceProductBindDeviceDao.delete(entity);
        deviceProductService.updateNumber(entity.getDeviceProduct());
        return ResultContent.buildSuccess();
    }

    public ResultContent deleteDevicesInfo(IDsParam param) {
        if (ObjectUtils.isEmpty(param.getIds())) {
            return ResultContent.buildFail("ids不能为空");
        }
        List<DeviceProductBindDevice> list = deviceProductBindDeviceDao.findByIdIn(param.getIds());
        if (ObjectUtils.isEmpty(list)) {
            return ResultContent.buildFail("数据不存在");
        }
        deviceProductBindDeviceDao.deleteAllById(param.getIds());
        List<DeviceProduct> deviceProducts = new ArrayList<>();
        list.stream().forEach(it -> {
            deviceProducts.add(it.getDeviceProduct());
        });
        deviceProducts.stream().forEach(it -> {
            deviceProductService.updateNumber(it);
        });
        return ResultContent.buildSuccess();
    }

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

    /**
     * 检查设备是否绑定了产品
     *
     * @param deviceId
     * @return
     */
    public ResultContent<DeviceProduct> checkAndGetDeviceProduct(String deviceId) {
        DeviceProductBindDevice deviceProductBindDevice = deviceProductBindDeviceDao.findTopByDeviceIdOrderByCreateTimeDesc(deviceId);
        if (ObjectUtils.isEmpty(deviceProductBindDevice)) {
            return ResultContent.buildFail("设备未配置产品信息");
        }
        return ResultContent.buildSuccess(deviceProductBindDevice.getDeviceProduct());
    }

    /**
     * 得到所有已绑定的设备
     *
     * @param projectOid
     * @return
     */
    public List<String> getAllBindDeviceIds(String projectOid) {
        List<DeviceProductBindDevice> list = deviceProductBindDeviceDao.findByProjectOid(projectOid);
        if (ObjectUtils.isNotEmpty(list)) {
            return list.parallelStream().map(it -> it.getDeviceId()).collect(Collectors.toList());
        }
        return Lists.newArrayList();
    }

    /**
     * 得到设备的绑定产品 关系信息
     *
     * @param deviceInfo
     * @return
     */
    public DeviceProductBindDevice getDeviceBindInfo(DeviceInfo deviceInfo) {
        if (deviceInfo != null) {
            return deviceProductBindDeviceDao.findTopByDeviceIdOrderByCreateTimeDesc(deviceInfo.getDeviceId());
        }
        return null;
    }

    public DeviceProduct getDeviceBindProductInfo(DeviceInfo deviceInfo) {
        if (deviceInfo != null) {
            DeviceProductBindDevice entity = deviceProductBindDeviceDao.findTopByDeviceIdOrderByCreateTimeDesc(deviceInfo.getDeviceId());
            if (entity != null) {
                return entity.getDeviceProduct();
            }
        }
        return null;
    }

    private DeviceProductBindDeviceModel toModel(DeviceProductBindDevice entity) {
        DeviceProductBindDeviceModel model = new DeviceProductBindDeviceModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
            model.setDeviceInfo(deviceInfoService.toModel(entity.getDeviceInfo()));
        }
        return model;
    }
}
