package com.ruoyi.web.modules.video.service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetSyncResultVo;
import com.ruoyi.web.modules.video.domain.dto.OpenCameraDto;
import com.ruoyi.web.modules.video.support.LivestockMonitorSyncRules;
import com.ruoyi.web.modules.video.support.ThirdPartyCameraClient;

/**
 * 第三方监控点位同步编排（入口见 Controller {@code POST .../sync}）。
 * <p>
 * 拉取全量摄像头列表（分页 HTTP 或 stub JSON），逐条 {@link LivestockMonitorSyncTxService#persistCamera}
 * 按 {@code monitor_id} upsert。单条失败记入 {@link YakAssetSyncResultVo#getFailMessages()}，不中断整批。
 * 配置与牧场同步共用 {@code third-party.farming}（enabled / mode / base-url 等）。
 * </p>
 */
@Service
public class LivestockMonitorSyncService
{
    /** 防止同一 JVM 内并发重复触发全量同步 */
    private final AtomicBoolean syncing = new AtomicBoolean(false);

    @Autowired
    private ThirdPartyCameraClient thirdPartyCameraClient;

    @Autowired
    private LivestockMonitorSyncTxService livestockMonitorSyncTxService;

    /**
     * 从第三方拉取监控列表并落库。
     *
     * @param operator 当前操作人（点击同步的用户名）
     * @return 同步统计（新增/更新/失败条数、失败明细、同步时间）
     */
    public YakAssetSyncResultVo syncFromThirdParty(String operator)
    {
        String syncBy = StringUtils.isNotEmpty(operator) ? operator.trim() : "";
        if (!syncing.compareAndSet(false, true))
        {
            throw new ServiceException(LivestockMonitorSyncRules.MSG_SYNC_IN_PROGRESS);
        }
        try
        {
            List<OpenCameraDto> cameras;
            try
            {
                cameras = thirdPartyCameraClient.fetchAllCameras();
            }
            catch (ServiceException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new ServiceException("第三方服务不可用：" + e.getMessage());
            }
            YakAssetSyncResultVo result = new YakAssetSyncResultVo();
            Date syncTime = new Date();
            if (CollectionUtils.isEmpty(cameras))
            {
                result.setSyncTime(syncTime);
                return result;
            }
            for (OpenCameraDto dto : cameras)
            {
                try
                {
                    boolean inserted = livestockMonitorSyncTxService.persistCamera(dto, syncTime, syncBy);
                    if (inserted)
                    {
                        result.setInsertCount(result.getInsertCount() + 1);
                    }
                    else
                    {
                        result.setUpdateCount(result.getUpdateCount() + 1);
                    }
                }
                catch (Exception e)
                {
                    result.setFailCount(result.getFailCount() + 1);
                    String key = dto != null && dto.getCameraId() != null
                            ? String.valueOf(dto.getCameraId())
                            : StringUtils.nvl(dto != null ? dto.getDeviceName() : null, "?");
                    result.getFailMessages().add(key + ": " + e.getMessage());
                }
            }
            result.setSyncTime(syncTime);
            return result;
        }
        finally
        {
            syncing.set(false);
        }
    }
}
