package com.adx.tracking.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对应 Go config.Config，通过环境变量加载所有配置项。
 * Spring Boot 的 @ConfigurationProperties 会自动将 application.properties
 * 中的 adx.* 属性绑定到此对象。
 */
@Component
@ConfigurationProperties(prefix = "adx")
public class AppProperties {

    // HTTP Server
    private String port = "8787";

    // Baidu ADX
    private String baiduAdxEndpoint = "http://debug.mobads.baidu.com/jbssp";
    private String baiduConversionBaseUrl = "https://media-interact-test.baidu.com";
    private String baiduCustomerName;
    private String baiduSecret;
    private String baiduAuctionPriceEncryption;
    private String baiduAuctionPriceEKey;
    private String baiduAuctionPriceIKey;
    private long baiduMediaId = 0;
    private String baiduAppId;
    private String baiduTagId;
    private String baiduAndroidAppId;
    private List<String> baiduAndroidTagIds = new ArrayList<>();
    private String baiduIosAppId;
    private List<String> baiduIosTagIds = new ArrayList<>();
    private long baiduBidFloor = 0;
    private int baiduActionType = 1;

    // Redis
    private String redisAddr = "127.0.0.1:6379";
    private String redisUsername;
    private String redisPassword;
    private int redisDb = 0;
    private String redisStream = "adx:events";
    private long redisStreamMaxLen = 50000;
    private Duration bidTtl = Duration.ofHours(24);

    // TiDB
    private String tidbUrl;
    private String tidbUsername;
    private String tidbPassword;

    // Task Lock
    private Duration taskLockTtl = Duration.ofSeconds(120);
    private Duration taskLockRenewInterval = Duration.ofSeconds(30);
    private Duration taskLockRetryInterval = Duration.ofSeconds(15);
    private boolean skipLeaderElection = false;

    // Worker
    private String workerGroup = "cold-writers";
    private String workerConsumer = defaultHostname();
    private int workerBatch = 100;

    // Conversion Sync
    private boolean conversionSyncEnabled = false;
    private Duration conversionSyncInterval = Duration.ofSeconds(300);
    private int conversionSyncDateOffsetDays = 0;
    private int conversionSyncPageSize = 1;
    private List<Integer> conversionSyncActs = List.of(1, 2, 3, 4, 5, 6, 8);

    // Kuaishou Act Mapping: "1:1,2:3,..." -> Map<baiduAct, kuaishouEvent>
    private Map<Integer, Integer> kuaishouActMap = new HashMap<>();
    // Extra Act Mapping: "2:5,2:6,..." -> Map<baiduAct, List<kuaishouEvent>>
    private Map<Integer, List<Integer>> kuaishouExtraActMap = new HashMap<>();

    // Callback Retry
    private boolean callbackRetryEnabled = false;
    private Duration callbackRetryInterval = Duration.ofSeconds(300);
    private int callbackRetryLimit = 100;

    private static String defaultHostname() {
        try {
            return java.net.InetAddress.getLocalHost().getHostName();
        } catch (Exception e) {
            return "worker-1";
        }
    }

    // ───── getters / setters ─────

    public String getPort() { return port; }
    public void setPort(String port) { this.port = port; }

    public String getBaiduAdxEndpoint() { return baiduAdxEndpoint; }
    public void setBaiduAdxEndpoint(String v) { this.baiduAdxEndpoint = v; }

    public String getBaiduConversionBaseUrl() { return baiduConversionBaseUrl; }
    public void setBaiduConversionBaseUrl(String v) { this.baiduConversionBaseUrl = v; }

    public String getBaiduCustomerName() { return baiduCustomerName; }
    public void setBaiduCustomerName(String v) { this.baiduCustomerName = v; }

    public String getBaiduSecret() { return baiduSecret; }
    public void setBaiduSecret(String v) { this.baiduSecret = v; }

    public String getBaiduAuctionPriceEncryption() { return baiduAuctionPriceEncryption; }
    public void setBaiduAuctionPriceEncryption(String v) { this.baiduAuctionPriceEncryption = v; }

    public String getBaiduAuctionPriceEKey() { return baiduAuctionPriceEKey; }
    public void setBaiduAuctionPriceEKey(String v) { this.baiduAuctionPriceEKey = v; }

    public String getBaiduAuctionPriceIKey() { return baiduAuctionPriceIKey; }
    public void setBaiduAuctionPriceIKey(String v) { this.baiduAuctionPriceIKey = v; }

    public long getBaiduMediaId() { return baiduMediaId; }
    public void setBaiduMediaId(long v) { this.baiduMediaId = v; }

    public String getBaiduAppId() { return baiduAppId; }
    public void setBaiduAppId(String v) { this.baiduAppId = v; }

    public String getBaiduTagId() { return baiduTagId; }
    public void setBaiduTagId(String v) { this.baiduTagId = v; }

    public String getBaiduAndroidAppId() { return baiduAndroidAppId; }
    public void setBaiduAndroidAppId(String v) { this.baiduAndroidAppId = v; }

    public List<String> getBaiduAndroidTagIds() { return baiduAndroidTagIds; }
    public void setBaiduAndroidTagIds(List<String> v) { this.baiduAndroidTagIds = v; }

    public String getBaiduIosAppId() { return baiduIosAppId; }
    public void setBaiduIosAppId(String v) { this.baiduIosAppId = v; }

    public List<String> getBaiduIosTagIds() { return baiduIosTagIds; }
    public void setBaiduIosTagIds(List<String> v) { this.baiduIosTagIds = v; }

    public long getBaiduBidFloor() { return baiduBidFloor; }
    public void setBaiduBidFloor(long v) { this.baiduBidFloor = v; }

    public int getBaiduActionType() { return baiduActionType; }
    public void setBaiduActionType(int v) { this.baiduActionType = v; }

    public String getRedisAddr() { return redisAddr; }
    public void setRedisAddr(String v) { this.redisAddr = v; }

    public String getRedisUsername() { return redisUsername; }
    public void setRedisUsername(String v) { this.redisUsername = v; }

    public String getRedisPassword() { return redisPassword; }
    public void setRedisPassword(String v) { this.redisPassword = v; }

    public int getRedisDb() { return redisDb; }
    public void setRedisDb(int v) { this.redisDb = v; }

    public String getRedisStream() { return redisStream; }
    public void setRedisStream(String v) { this.redisStream = v; }

    public long getRedisStreamMaxLen() { return redisStreamMaxLen; }
    public void setRedisStreamMaxLen(long v) { this.redisStreamMaxLen = v; }

    public Duration getBidTtl() { return bidTtl; }
    public void setBidTtl(Duration v) { this.bidTtl = v; }

    public String getTidbUrl() { return tidbUrl; }
    public void setTidbUrl(String v) { this.tidbUrl = v; }

    public String getTidbUsername() { return tidbUsername; }
    public void setTidbUsername(String v) { this.tidbUsername = v; }

    public String getTidbPassword() { return tidbPassword; }
    public void setTidbPassword(String v) { this.tidbPassword = v; }

    public Duration getTaskLockTtl() { return taskLockTtl; }
    public void setTaskLockTtl(Duration v) { this.taskLockTtl = v; }

    public Duration getTaskLockRenewInterval() { return taskLockRenewInterval; }
    public void setTaskLockRenewInterval(Duration v) { this.taskLockRenewInterval = v; }

    public Duration getTaskLockRetryInterval() { return taskLockRetryInterval; }
    public void setTaskLockRetryInterval(Duration v) { this.taskLockRetryInterval = v; }

    public boolean isSkipLeaderElection() { return skipLeaderElection; }
    public void setSkipLeaderElection(boolean v) { this.skipLeaderElection = v; }

    public String getWorkerGroup() { return workerGroup; }
    public void setWorkerGroup(String v) { this.workerGroup = v; }

    public String getWorkerConsumer() { return workerConsumer; }
    public void setWorkerConsumer(String v) { this.workerConsumer = v; }

    public int getWorkerBatch() { return workerBatch; }
    public void setWorkerBatch(int v) { this.workerBatch = v; }

    public boolean isConversionSyncEnabled() { return conversionSyncEnabled; }
    public void setConversionSyncEnabled(boolean v) { this.conversionSyncEnabled = v; }

    public Duration getConversionSyncInterval() { return conversionSyncInterval; }
    public void setConversionSyncInterval(Duration v) { this.conversionSyncInterval = v; }

    public int getConversionSyncDateOffsetDays() { return conversionSyncDateOffsetDays; }
    public void setConversionSyncDateOffsetDays(int v) { this.conversionSyncDateOffsetDays = v; }

    public int getConversionSyncPageSize() { return conversionSyncPageSize; }
    public void setConversionSyncPageSize(int v) { this.conversionSyncPageSize = v; }

    public List<Integer> getConversionSyncActs() { return conversionSyncActs; }
    public void setConversionSyncActs(List<Integer> v) { this.conversionSyncActs = v; }

    public Map<Integer, Integer> getKuaishouActMap() { return kuaishouActMap; }
    public void setKuaishouActMap(Map<Integer, Integer> v) { this.kuaishouActMap = v; }

    public Map<Integer, List<Integer>> getKuaishouExtraActMap() { return kuaishouExtraActMap; }
    public void setKuaishouExtraActMap(Map<Integer, List<Integer>> v) { this.kuaishouExtraActMap = v; }

    public boolean isCallbackRetryEnabled() { return callbackRetryEnabled; }
    public void setCallbackRetryEnabled(boolean v) { this.callbackRetryEnabled = v; }

    public Duration getCallbackRetryInterval() { return callbackRetryInterval; }
    public void setCallbackRetryInterval(Duration v) { this.callbackRetryInterval = v; }

    public int getCallbackRetryLimit() { return callbackRetryLimit; }
    public void setCallbackRetryLimit(int v) { this.callbackRetryLimit = v; }
}
