package com.ycwl.basic.integration.device.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.ycwl.basic.integration.common.exception.IntegrationException;
import com.ycwl.basic.integration.common.response.CommonResponse;
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
import com.ycwl.basic.integration.device.client.DeviceV2Client;
import com.ycwl.basic.integration.device.dto.status.DeviceStatusDTO;
import com.ycwl.basic.integration.device.dto.status.OnlineStatusResponseDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceStatusIntegrationService {

    private final DeviceV2Client deviceStatusClient;
    private final IntegrationFallbackService fallbackService;
    
    private static final String SERVICE_NAME = "zt-device";

    public DeviceStatusDTO getDeviceStatus(String deviceNo) {
        log.debug("获取设备状态, deviceNo: {}", deviceNo);
        return fallbackService.executeWithFallback(
            SERVICE_NAME,
            "device:status:" + deviceNo,
            () -> {
                CommonResponse<DeviceStatusDTO> response = deviceStatusClient.getDeviceStatus(deviceNo);
                return handleResponse(response, "获取设备状态失败");
            },
            DeviceStatusDTO.class
        );
    }

    public OnlineStatusResponseDTO isDeviceOnline(String deviceNo) {
        log.debug("检查设备是否在线, deviceNo: {}", deviceNo);
        return fallbackService.executeWithFallback(
            SERVICE_NAME,
            "device:online:" + deviceNo,
            () -> {
                CommonResponse<OnlineStatusResponseDTO> response = deviceStatusClient.isDeviceOnline(deviceNo);
                return handleResponse(response, "检查设备在线状态失败");
            },
            OnlineStatusResponseDTO.class
        );
    }

    /**
     * 获取所有在线设备（带降级，使用TypeReference保留泛型信息）
     */
    public List<DeviceStatusDTO> getAllOnlineDevices() {
        log.debug("获取所有在线设备");
        return fallbackService.executeWithFallback(
            SERVICE_NAME,
            "devices:online:all",
            () -> {
                CommonResponse<List<DeviceStatusDTO>> response = deviceStatusClient.getAllOnlineDevices();
                return handleResponse(response, "获取所有在线设备失败");
            },
            new TypeReference<List<DeviceStatusDTO>>() {}
        );
    }

    public void setDeviceOffline(String deviceNo) {
        log.debug("设置设备离线, deviceNo: {}", deviceNo);
        CommonResponse<String> response = deviceStatusClient.setDeviceOffline(deviceNo);
        handleResponse(response, "设置设备离线失败");
    }

    public void setDeviceOnline(String deviceNo) {
        log.debug("设置设备在线, deviceNo: {}", deviceNo);
        CommonResponse<String> response = deviceStatusClient.setDeviceOnline(deviceNo);
        handleResponse(response, "设置设备在线失败");
    }

    public void cleanExpiredDevices() {
        log.debug("清理过期设备状态");
        CommonResponse<String> response = deviceStatusClient.cleanExpiredDevices();
        handleResponse(response, "清理过期设备状态失败");
    }

    /**
     * 安全地获取设备状态
     */
    public Optional<DeviceStatusDTO> getDeviceStatusSafely(String deviceNo) {
        try {
            DeviceStatusDTO status = getDeviceStatus(deviceNo);
            return Optional.ofNullable(status);
        } catch (Exception e) {
            log.warn("获取设备状态异常: deviceNo={}, error={}", deviceNo, e.getMessage());
            return Optional.empty();
        }
    }

    /**
     * 安全地检查设备是否在线
     */
    public boolean isDeviceOnlineSafely(String deviceNo) {
        try {
            OnlineStatusResponseDTO response = isDeviceOnline(deviceNo);
            return response != null && Boolean.TRUE.equals(response.getIsOnline());
        } catch (Exception e) {
            log.warn("检查设备在线状态异常: deviceNo={}, error={}", deviceNo, e.getMessage());
            return false;
        }
    }

    /**
     * 批量检查设备是否在线
     */
    public boolean areAllDevicesOnline(List<String> deviceNos) {
        if (deviceNos == null || deviceNos.isEmpty()) {
            return true;
        }
        
        log.debug("批量检查设备在线状态, deviceNos: {}", deviceNos);
        for (String deviceNo : deviceNos) {
            if (!isDeviceOnlineSafely(deviceNo)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 批量设置设备离线
     */
    public void setDevicesOffline(List<String> deviceNos) {
        if (deviceNos == null || deviceNos.isEmpty()) {
            return;
        }
        
        log.debug("批量设置设备离线, deviceNos: {}", deviceNos);
        for (String deviceNo : deviceNos) {
            try {
                setDeviceOffline(deviceNo);
            } catch (Exception e) {
                log.error("设置设备离线失败: deviceNo={}, error={}", deviceNo, e.getMessage());
            }
        }
    }

    /**
     * 批量设置设备在线
     */
    public void setDevicesOnline(List<String> deviceNos) {
        if (deviceNos == null || deviceNos.isEmpty()) {
            return;
        }
        
        log.debug("批量设置设备在线, deviceNos: {}", deviceNos);
        for (String deviceNo : deviceNos) {
            try {
                setDeviceOnline(deviceNo);
            } catch (Exception e) {
                log.error("设置设备在线失败: deviceNo={}, error={}", deviceNo, e.getMessage());
            }
        }
    }

    /**
     * 获取在线设备数量
     */
    public int getOnlineDeviceCount() {
        try {
            List<DeviceStatusDTO> onlineDevices = getAllOnlineDevices();
            return onlineDevices != null ? onlineDevices.size() : 0;
        } catch (Exception e) {
            log.warn("获取在线设备数量失败: {}", e.getMessage());
            return 0;
        }
    }

    /**
     * 获取指定设备编号列表中的在线设备
     */
    public List<String> getOnlineDeviceNos(List<String> deviceNos) {
        if (deviceNos == null || deviceNos.isEmpty()) {
            return List.of();
        }
        
        return deviceNos.stream()
            .filter(this::isDeviceOnlineSafely)
            .toList();
    }

    /**
     * 获取指定设备编号列表中的离线设备
     */
    public List<String> getOfflineDeviceNos(List<String> deviceNos) {
        if (deviceNos == null || deviceNos.isEmpty()) {
            return List.of();
        }
        
        return deviceNos.stream()
            .filter(deviceNo -> !isDeviceOnlineSafely(deviceNo))
            .toList();
    }

    private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
        if (response == null || !response.isSuccess()) {
            String msg = response != null && response.getMessage() != null 
                        ? response.getMessage() 
                        : errorMessage;
            Integer code = response != null ? response.getCode() : 5000;
            throw new IntegrationException(code, msg, SERVICE_NAME);
        }
        return response.getData();
    }
}