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

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.common.response.PageResponse;
import com.ycwl.basic.integration.device.dto.device.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceIntegrationService {

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

    public DeviceV2DTO getDevice(Long deviceId) {
        log.debug("获取设备信息, deviceId: {}", deviceId);
        return fallbackService.executeWithFallback(
            SERVICE_NAME,
            "device:" + deviceId, 
            () -> {
                CommonResponse<DeviceV2DTO> response = deviceV2Client.getDevice(deviceId);
                return handleResponse(response, "获取设备信息失败");
            },
            DeviceV2DTO.class
        );
    }

    public DeviceV2DTO getDeviceByNo(String deviceNo) {
        log.debug("根据设备编号获取设备信息, deviceNo: {}", deviceNo);
        return fallbackService.executeWithFallback(
            SERVICE_NAME,
            "device:no:" + deviceNo,
            () -> {
                CommonResponse<DeviceV2DTO> response = deviceV2Client.getDeviceByNo(deviceNo);
                return handleResponse(response, "根据设备编号获取设备信息失败");
            },
            DeviceV2DTO.class
        );
    }

    public DeviceV2DTO createDevice(CreateDeviceRequest request) {
        log.debug("创建设备, name: {}, no: {}, type: {}", request.getName(), request.getNo(), request.getType());
        CommonResponse<DeviceV2DTO> response = deviceV2Client.createDevice(request);
        return handleResponse(response, "创建设备失败");
    }

    public void updateDevice(Long deviceId, UpdateDeviceRequest request) {
        log.debug("更新设备信息, deviceId: {}", deviceId);
        CommonResponse<String> response = deviceV2Client.updateDevice(deviceId, request);
        handleResponse(response, "更新设备信息失败");
        // 清理设备相关缓存
        fallbackService.clearFallbackCache(SERVICE_NAME, "device:" + deviceId);
    }

    public void deleteDevice(Long deviceId) {
        log.debug("删除设备, deviceId: {}", deviceId);
        CommonResponse<String> response = deviceV2Client.deleteDevice(deviceId);
        handleResponse(response, "删除设备失败");
        // 清理设备相关缓存
        fallbackService.clearFallbackCache(SERVICE_NAME, "device:" + deviceId);
    }

    public PageResponse<DeviceV2DTO> listDevices(Integer page, Integer pageSize, String name, String no,
                                          String type, Integer isActive, Long scenicId, String scenicIds) {
        log.debug("分页查询设备列表, page: {}, pageSize: {}, name: {}, no: {}, type: {}, isActive: {}, scenicId: {}, scenicIds: {}",
                page, pageSize, name, no, type, isActive, scenicId, scenicIds);

        // 参数优先级处理：scenicId 优先于 scenicIds
        Long finalScenicId = null;
        String finalScenicIds = null;

        if (scenicId != null) {
            // 优先使用单个 scenicId（向后兼容）
            finalScenicId = scenicId;
            finalScenicIds = null;
            log.debug("使用单个 scenicId 参数: {}", finalScenicId);
        } else if (scenicIds != null && !scenicIds.trim().isEmpty()) {
            // 使用 scenicIds
            finalScenicId = null;
            finalScenicIds = scenicIds;
            log.debug("使用 scenicIds 参数: {}", finalScenicIds);
        }

        CommonResponse<PageResponse<DeviceV2DTO>> response = deviceV2Client.listDevices(
                page, pageSize, name, no, type, isActive, finalScenicId, finalScenicIds);
        return handleResponse(response, "分页查询设备列表失败");
    }

    /**
     * 创建IPC摄像头设备
     */
    public DeviceV2DTO createIpcDevice(String name, String deviceNo, Long scenicId) {
        CreateDeviceRequest request = new CreateDeviceRequest();
        request.setName(name);
        request.setNo(deviceNo);
        request.setType("IPC");
        request.setIsActive(1);
        request.setScenicId(scenicId);
        request.setSort(0);
        return createDevice(request);
    }

    /**
     * 创建IPC摄像头设备（带排序）
     */
    public DeviceV2DTO createIpcDeviceWithSort(String name, String deviceNo, Long scenicId, Integer sort) {
        CreateDeviceRequest request = new CreateDeviceRequest();
        request.setName(name);
        request.setNo(deviceNo);
        request.setType("IPC");
        request.setIsActive(1);
        request.setScenicId(scenicId);
        request.setSort(sort != null ? sort : 0);
        return createDevice(request);
    }

    /**
     * 创建自定义设备
     */
    public DeviceV2DTO createCustomDevice(String name, String deviceNo, Long scenicId) {
        CreateDeviceRequest request = new CreateDeviceRequest();
        request.setName(name);
        request.setNo(deviceNo);
        request.setType("CUSTOM");
        request.setIsActive(1);
        request.setScenicId(scenicId);
        request.setSort(0);
        return createDevice(request);
    }

    /**
     * 创建自定义设备（带排序）
     */
    public DeviceV2DTO createCustomDeviceWithSort(String name, String deviceNo, Long scenicId, Integer sort) {
        CreateDeviceRequest request = new CreateDeviceRequest();
        request.setName(name);
        request.setNo(deviceNo);
        request.setType("CUSTOM");
        request.setIsActive(1);
        request.setScenicId(scenicId);
        request.setSort(sort != null ? sort : 0);
        return createDevice(request);
    }

    /**
     * 启用设备
     */
    public void enableDevice(Long deviceId) {
        UpdateDeviceRequest request = new UpdateDeviceRequest();
        request.setIsActive(1);
        updateDevice(deviceId, request);
    }

    /**
     * 禁用设备
     */
    public void disableDevice(Long deviceId) {
        UpdateDeviceRequest request = new UpdateDeviceRequest();
        request.setIsActive(0);
        updateDevice(deviceId, request);
    }

    /**
     * 更新设备排序
     */
    public void updateDeviceSort(Long deviceId, Integer sort) {
        log.debug("更新设备排序, deviceId: {}, sort: {}", deviceId, sort);
        UpdateDeviceRequest request = new UpdateDeviceRequest();
        request.setSort(sort);
        updateDevice(deviceId, request);
    }

    /**
     * 获取景区的IPC设备列表
     */
    public PageResponse<DeviceV2DTO> getScenicIpcDevices(Long scenicId, Integer page, Integer pageSize) {
        return listDevices(page, pageSize, null, null, "IPC", 1, scenicId, null);
    }

    /**
     * 获取景区的所有激活设备
     */
    public PageResponse<DeviceV2DTO> getScenicActiveDevices(Long scenicId, Integer page, Integer pageSize) {
        return listDevices(page, pageSize, null, null, null, 1, scenicId, null);
    }

    /**
     * 根据配置条件筛选设备
     */
    public FilterDevicesByConfigsResponse filterDevicesByConfigs(FilterDevicesByConfigsRequest request) {
        log.debug("根据配置条件筛选设备, page: {}, pageSize: {}, filterLogic: {}, configFilters: {}",
                request.getPage(), request.getPageSize(), request.getFilterLogic(), request.getConfigFilters());
        CommonResponse<FilterDevicesByConfigsResponse> response = deviceV2Client.filterDevicesByConfigs(request);
        return handleResponse(response, "根据配置条件筛选设备失败");
    }

    /**
     * 查找缺少指定配置的设备
     */
    public FilterDevicesByConfigsResponse findDevicesWithMissingConfig(String configKey, Integer page, Integer pageSize) {
        FilterDevicesByConfigsRequest request = new FilterDevicesByConfigsRequest();
        request.setPage(page != null ? page : 1);
        request.setPageSize(pageSize != null ? pageSize : 20);
        request.setConfigFilters(List.of(new ConfigFilter(configKey, null, "is_null")));
        return filterDevicesByConfigs(request);
    }

    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, "zt-device");
        }
        return response.getData();
    }
}