package com.fs.fssync.sink;

import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.databind.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.Serializable;
import java.lang.reflect.Field;

@Slf4j
public abstract class AbstractCdcSinkStrategy<T> implements CdcSinkStrategy<T>, Serializable {

    private final ObjectMapper objectMapper;
    @Autowired
    protected RedisTemplate<String, Object> redisTemplate;

    protected AbstractCdcSinkStrategy() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        this.objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // 添加此行以忽略未知属性
        this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Override
    public void process(String cdcData) throws Exception {

        JsonNode rootNode = objectMapper.readTree(cdcData);
        String op = rootNode.get("op").asText();

        if ("c".equals(op) || "r".equals(op)) {
            T after = objectMapper.treeToValue(rootNode.get("after"), getEntityClass());
            handleCreate(after);
        } else if ("u".equals(op)) {
            T after = objectMapper.treeToValue(rootNode.get("after"), getEntityClass());
            handleUpdate(after);
        } else if ("d".equals(op)) {
            T before = objectMapper.treeToValue(rootNode.get("before"), getEntityClass());
            handleDelete(before);
        } else {
            log.warn("未知的操作类型: {}", op);
        }
    }

    protected void handleCreate(T entity) throws Exception {
        Object id = getIdValue(entity);
        if (id != null) {
            String key = getKeyPrefix() + id;
            redisTemplate.opsForValue().set(key, entity);
            log.info("数据已写入 Redis, key={}", key);
        }
    }

    protected void handleUpdate(T entity) throws Exception {
        handleCreate(entity);
    }

    protected void handleDelete(T entity) throws Exception {
        Object id = getIdValue(entity);
        if (id != null) {
            String key = getKeyPrefix() + id;
            redisTemplate.delete(key);
            log.info("数据已从 Redis 删除, key={}", key);
        }
    }

    protected String getIdField(){
        return "id";
    }

    protected Object getIdValue(T entity) throws Exception {
        // 获取ID字段的值，可以改为使用反射工具类
        Field field = getEntityClass().getDeclaredField(getIdField());
        field.setAccessible(true);
        return field.get(entity);
    }


}
