package com.adx.tracking.conversionsync;

import com.adx.tracking.media.kuaishou.KuaishouClient;
import com.adx.tracking.storage.TiDBColdStore;
import com.adx.tracking.storage.model.MediaCallbackRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Instant;
import java.util.List;

/**
 * 对应 Go internal/conversionsync/retry.go 的 RetryService。
 * 查询 TiDB 中未成功的快手回调记录，逐条重试。
 */
public class RetryService {

    private static final Logger log = LoggerFactory.getLogger(RetryService.class);

    private final TiDBColdStore coldStore;
    private final KuaishouClient kuaishouClient;
    private final int defaultLimit;

    public RetryService(TiDBColdStore coldStore, KuaishouClient kuaishouClient, int defaultLimit) {
        this.coldStore      = coldStore;
        this.kuaishouClient = kuaishouClient;
        this.defaultLimit   = defaultLimit > 0 ? defaultLimit : 100;
    }

    /**
     * 对应 Go RetryService.RetryKuaishouCallbacks()。
     * @param limit 最多处理条数，<=0 则使用 defaultLimit
     */
    public RetryResult retryKuaishouCallbacks(int limit) {
        if (limit <= 0) limit = defaultLimit;

        List<MediaCallbackRecord> pending = coldStore.pendingMediaCallbacks("kuaishou", limit);
        RetryResult result = new RetryResult();
        result.fetched = pending.size();

        for (MediaCallbackRecord record : pending) {
            MediaCallbackRecord retryRecord;
            try {
                retryRecord = kuaishouClient.retryCallback(record);
                result.sent++;
            } catch (Exception e) {
                result.failed++;
                retryRecord = copyRecord(record);
                retryRecord.setAttempt(record.getAttempt() + 1);
                retryRecord.setOk(false);
                retryRecord.setErrorMessage(e.getMessage());
                retryRecord.setCreatedAt(Instant.now());
                try { coldStore.saveMediaCallback(retryRecord); } catch (Exception ignored) {}
                continue;
            }
            // 对应 Go: 成功重试后 saveMediaCallback 失败则终止当前批次
            coldStore.saveMediaCallback(retryRecord);
        }
        return result;
    }

    private static MediaCallbackRecord copyRecord(MediaCallbackRecord src) {
        MediaCallbackRecord copy = new MediaCallbackRecord();
        copy.setDedupeKey(src.getDedupeKey());
        copy.setMedia(src.getMedia());
        copy.setQk(src.getQk());
        copy.setCallbackUrl(src.getCallbackUrl());
        copy.setEventType(src.getEventType());
        copy.setEventTimeMs(src.getEventTimeMs());
        copy.setPurchase(src.getPurchase());
        copy.setStatus(src.getStatus());
        copy.setOk(src.isOk());
        copy.setAttempt(src.getAttempt());
        copy.setResponseBody(src.getResponseBody());
        copy.setErrorMessage(src.getErrorMessage());
        copy.setCreatedAt(src.getCreatedAt());
        return copy;
    }

    public static class RetryResult {
        public int fetched, sent, failed;
    }
}
