package com.ruoyi.web.modules.industryservice.support;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenEnvMonitoringDto;

/**
 * 第三方 IoT 环境监测客户端实现。
 */
@Component
public class ThirdPartyIotEnvMonitoringClientImpl implements ThirdPartyIotEnvMonitoringClient
{
    private static final String STUB_RESOURCE = "thirdparty/stub-iot-env-monitoring.json";

    private static final String LIST_PATH = "/open-api/v1/iot/env-monitoring";

    private final ObjectMapper objectMapper = ThirdPartyFarmingHttpSupport.createObjectMapper();

    @Autowired
    private ThirdPartyFarmingProperties properties;

    @Override
    public List<OpenEnvMonitoringDto> fetchAll()
    {
        return fetchIncremental(null, null, null);
    }

    @Override
    public List<OpenEnvMonitoringDto> fetchIncremental(Date startTime, Date endTime, Date updatedAfter)
    {
        if (!properties.isEnabled())
        {
            throw new ServiceException("第三方 IoT 环境监测同步未启用");
        }
        if ("http".equalsIgnoreCase(properties.getMode()))
        {
            Map<String, String> params = IotSyncSupport.buildIncrementalQueryParams(startTime, endTime, updatedAfter);
            return ThirdPartyFarmingPageFetcher.fetchAllPages(properties, objectMapper, LIST_PATH,
                    new TypeReference<OpenApiResponse<OpenApiPageResult<OpenEnvMonitoringDto>>>() { }, "环境监测", params);
        }
        return filterStubRows(ThirdPartyFarmingPageFetcher.fetchFromStub(objectMapper, STUB_RESOURCE,
                new TypeReference<List<OpenEnvMonitoringDto>>() { }, "环境监测"), null, null, startTime, endTime);
    }

    @Override
    public List<OpenEnvMonitoringDto> fetchByFarmEnclosure(Long farmId, Long enclosureId, Date startTime, Date endTime)
    {
        if (!properties.isEnabled())
        {
            throw new ServiceException("第三方 IoT 环境监测同步未启用");
        }
        if (farmId == null || enclosureId == null)
        {
            throw new ServiceException("养殖场与圈舍不能为空");
        }
        if ("http".equalsIgnoreCase(properties.getMode()))
        {
            Map<String, String> params = IotSyncSupport.buildEnvMonitoringQueryParams(
                    farmId, enclosureId, startTime, endTime);
            return ThirdPartyFarmingPageFetcher.fetchAllPages(properties, objectMapper, LIST_PATH,
                    new TypeReference<OpenApiResponse<OpenApiPageResult<OpenEnvMonitoringDto>>>() { }, "环境监测", params);
        }
        return filterStubRows(ThirdPartyFarmingPageFetcher.fetchFromStub(objectMapper, STUB_RESOURCE,
                new TypeReference<List<OpenEnvMonitoringDto>>() { }, "环境监测"), farmId, enclosureId, startTime, endTime);
    }

    private static List<OpenEnvMonitoringDto> filterStubRows(List<OpenEnvMonitoringDto> all, Long farmId,
            Long enclosureId, Date startTime, Date endTime)
    {
        if (startTime == null && endTime == null && farmId == null && enclosureId == null)
        {
            return all;
        }
        List<OpenEnvMonitoringDto> filtered = new ArrayList<>();
        for (OpenEnvMonitoringDto row : all)
        {
            if (row == null)
            {
                continue;
            }
            if (farmId != null && !farmId.equals(row.getFarmId()))
            {
                continue;
            }
            if (enclosureId != null && !enclosureId.equals(row.getEnclosureId()))
            {
                continue;
            }
            Date eventTime = FarmingSyncSupport.parseThirdPartyTime(row.getMonitoringTime(), null);
            if (IotSyncSupport.withinIncrementalWindow(eventTime, startTime, endTime))
            {
                filtered.add(row);
            }
        }
        return filtered;
    }
}
