package org.agt.module.license.framework.canal;

import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.Message;
import jakarta.annotation.Resource;
import org.agt.module.license.service.license.LicenseServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;
import java.util.List;

@EnableAsync
@Service
public class CanalService {

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

    @Resource
    private LicenseServiceImpl licenseService;

    @Async
    public void startCanalListener() {
        // 创建连接
        CanalConnector connector = CanalConnectors.newSingleConnector(
                new InetSocketAddress("127.0.0.1", 11111),
                "example", // Canal instance 名称
                "", "");   // 用户名/密码（可为空）

        try {
            connector.connect();
            connector.subscribe("agt-cloud\\.crm_license"); // 订阅库（正则方式）
            connector.rollback();

            System.out.println("✅ Canal client 启动成功，开始监听数据库变化...");

            while (true) {
                // 拉取数据，每次最多 100 条
                Message message = connector.getWithoutAck(100);
                long batchId = message.getId();

                if (batchId == -1 || message.getEntries().isEmpty()) {
                    Thread.sleep(1000);
                } else {
                    handleEntry(message.getEntries());
                }
                connector.ack(batchId); // 提交确认
            }

        } catch (Exception e) {
            log.error("canal启动失败：{}", e.getMessage(), e);
        } finally {
            connector.disconnect();
        }
    }

    private void handleEntry(List<CanalEntry.Entry> entries) throws Exception {
        for (CanalEntry.Entry entry : entries) {
            if (entry.getEntryType() != CanalEntry.EntryType.ROWDATA) {
                continue;
            }

            CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
            CanalEntry.EventType eventType = rowChange.getEventType();

            String tableName = entry.getHeader().getTableName();
            System.out.printf("📢 [监听到] 数据库表：%s，事件类型：%s%n", tableName, eventType);

            for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
                switch (eventType) {
                    case INSERT:
                        break;
                    case UPDATE:
                        printColumns("BEFORE UPDATE", rowData.getBeforeColumnsList());
                        printColumns("AFTER UPDATE", rowData.getAfterColumnsList());
                        // 更新后的业务逻辑
                        if ("crm_license".equals(tableName)) {
                            rowData.getAfterColumnsList().forEach(column -> {
                                if ("state".equals(column.getName()) && "3".equals(column.getValue()) && column.getUpdated()) {
                                    licenseService.genLicenseTask();
                                }
                            });
                        }
                        break;
                    case DELETE:
                        break;
                    default:
                        break;
                }
            }
        }
    }

    private void printColumns(String label, List<CanalEntry.Column> columns) {
        System.out.println("==== " + label + " ====");
        for (CanalEntry.Column column : columns) {
            System.out.printf("%s = %s (updated=%s)%n",
                    column.getName(), column.getValue(), column.getUpdated());
        }
    }
}
