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

import java.util.Date;
import java.util.List;
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.web.modules.industryservice.domain.dto.YakAssetBundleDto;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetSyncResultVo;
import com.ruoyi.web.modules.industryservice.support.ThirdPartyYakClient;
import com.ruoyi.web.modules.industryservice.support.YakAssetStatusMapper;

/**
 * 第三方<strong>入栏建档（牦牛生物资产）</strong>同步编排。
 * <p>
 * 接口：{@code GET /open-api/v1/farming/entry-filings} → 落库 {@code biz_yak_asset} 及可选子表。
 * 在全量同步中由 {@link LivestockFinanceMasterSyncService} 作为最后一步调用；
 * 也可单独运行（前提是养殖场等基础数据已同步，否则 pasture_id 可能无法解析）。
 * </p>
 *
 * <h3>处理流程</h3>
 * <ol>
 *   <li>{@link ThirdPartyYakClient#fetchAll()} 分页拉取并映射为 {@link YakAssetBundleDto}</li>
 *   <li>逐头调用 {@link YakAssetBundleSyncTxService#persistBundle}（单头独立事务）</li>
 *   <li>汇总 insert/update/fail 计数</li>
 * </ol>
 *
 * <h3>并发与容错</h3>
 * <p>
 * {@link #syncLock} 防止同一服务实例并发同步；单头失败仅增加 failCount，已成功落库的头不回滚。
 * </p>
 */
@Service
public class YakAssetSyncService
{
    /** 入栏建档同步互斥锁 */
    private final Object syncLock = new Object();

    @Autowired
    private ThirdPartyYakClient thirdPartyYakClient;

    @Autowired
    private YakAssetBundleSyncTxService bundleSyncTxService;

    /**
     * 从第三方拉取全量入栏建档列表并逐头 upsert。
     *
     * @return 新增/更新/失败头数；失败明细 key 为 yakNo
     */
    public YakAssetSyncResultVo syncFromThirdParty()
    {
        synchronized (syncLock)
        {
            List<YakAssetBundleDto> bundles;
            try
            {
                bundles = thirdPartyYakClient.fetchAll();
            }
            catch (ServiceException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new ServiceException("第三方服务不可用：" + e.getMessage());
            }
            YakAssetSyncResultVo result = new YakAssetSyncResultVo();
            Date syncTime = new Date();
            if (CollectionUtils.isEmpty(bundles))
            {
                result.setSyncTime(syncTime);
                return result;
            }
            for (YakAssetBundleDto bundle : bundles)
            {
                try
                {
                    boolean inserted = bundleSyncTxService.persistBundle(bundle, syncTime);
                    if (inserted)
                    {
                        result.setInsertCount(result.getInsertCount() + 1);
                    }
                    else
                    {
                        result.setUpdateCount(result.getUpdateCount() + 1);
                    }
                }
                catch (Exception e)
                {
                    result.setFailCount(result.getFailCount() + 1);
                    String yakNo = bundle != null && bundle.getAsset() != null ? bundle.getAsset().getYakNo() : "?";
                    result.getFailMessages().add(yakNo + ": " + e.getMessage());
                }
            }
            result.setSyncTime(syncTime);
            return result;
        }
    }

    /** 第三方状态码 → 本地 asset_status（供测试或扩展使用） */
    public static int mapThirdPartyStatus(String code)
    {
        return YakAssetStatusMapper.mapToLocalStatus(code);
    }
}
