package modules.nftt;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import common.jfinal.AppConfig;
import common.model.Nftt;
import common.utils.bsn.BsnSDK;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.TimeUnit;

public class NfttStatusMaintenanceTask implements Runnable {
    private static final Logger LOGGER = LoggerFactory.getLogger(NfttStatusMaintenanceTask.class);

    // 任务是否应该停止的标志
    private volatile boolean running = true; // 使用 volatile 确保多线程可见性
    
    public NfttStatusMaintenanceTask() {
        LOGGER.info("NftStatusMaintenanceTask 实例已创建。");
    }
    
    @Override
    public void run() {
        LOGGER.info("NftStatusMaintenanceTask 后台任务开始运行...");
        while (running) { // 循环直到收到停止指令
            try {
                // 每次循环后休眠一段时间，避免CPU空转，并控制检查频率
                Thread.sleep(TimeUnit.SECONDS.toMillis(10)); // 每 10 秒检查一次
                
                // 只处理已支付但未确权的
                String sql = "SELECT * FROM t_nftt WHERE bsn_token_id IS NULL";
                flushNftStatus(Nftt.dao.find(sql));
            } catch (InterruptedException e) {
                LOGGER.warn("NftStatusMaintenanceTask 因中断而停止。");
                Thread.currentThread().interrupt(); // 重新设置中断状态
                running = false; // 退出循环
            } catch (Exception e) {
                // 捕获所有其他异常，记录日志，但保持线程继续运行
                LOGGER.error("NftStatusMaintenanceTask 执行异常: {}", e.getMessage(), e);
                // 可以在这里添加告警，或在短时间后重试
                try {
                    Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // 发生错误时短暂休眠，避免错误日志刷屏
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    running = false;
                }
            }
        }
        LOGGER.info("NftStatusMaintenanceTask 后台任务已停止运行。");
    }

    private void flushNftStatus(List<Nftt> list) throws InterruptedException {
        // 遍历列表，处理 BSN 状态更新逻辑
        // 这个逻辑会影响分页查询的性能，特别是当 BsnSDK.search 是耗时操作时
        // 建议将其移到异步处理或专门的同步任务中
        for (Nftt nftt : list) {
            // bsnTokenId 如果不为空，说明已经处理过上链结果，跳过
            if (StrKit.notBlank(nftt.getBsnTokenId())) {
                continue;
            }

            try {
                // 调用 BSN SDK 查询上链状态
                // 确保 BsnSDK.search 返回的是 JSONObject，且参数正确
                JSONObject searchObject = BsnSDK.search("DLTBH_NFT_" + nftt.getLong("id")); // 假设 id 是 Long 类型

                // 记录原始响应，便于调试
                nftt.set("bsn_status_json", searchObject.toJSONString()); // 假设字段名为 bsn_status_json
                // 不需要在这里立即 update()，可以在最后处理完所有状态后再批量更新，或在成功时更新
                // nftt.update(); // 暂时移除，避免频繁更新

                // 校验 BSN SDK 响应
                if (searchObject.getInteger("code") == null || searchObject.getInteger("code") != 0) {
                    throw new RuntimeException("BSN API查询失败，返回值与预期不符或code不为0：" + searchObject.toJSONString());
                }

                JSONObject data = searchObject.getJSONObject("data");
                if (data == null) {
                    throw new RuntimeException("BSN API响应数据为空：" + searchObject.toJSONString());
                }

                Integer status = data.getInteger("status");
                if (status == null) {
                    throw new RuntimeException("BSN API响应状态字段缺失：" + searchObject.toJSONString());
                }

                if (status == 2) { // 假设 status == 2 表示上链失败
                    nftt.set("bsn_token_id", "-1"); // 标记上链失败
                    nftt.set("bsn_status_json", searchObject.toJSONString()); // 更新失败状态信息
                    nftt.update(); // 立即更新失败状态
                    throw new RuntimeException("BSN 上链失败，链上的错误：" + searchObject.toJSONString());
                }

                if (status == 1) { // 假设 status == 1 表示上链成功且有 tokenId
                    String tokenId = data.getString("tokenId");
                    if (StrKit.isBlank(tokenId)) {
                        throw new RuntimeException("BSN 上链成功但 tokenId 为空：" + searchObject.toJSONString());
                    }
                    nftt.set("bsn_token_id", tokenId);
                    nftt.set("bsn_status_json", searchObject.toJSONString()); // 更新成功状态信息
                    nftt.update(); // 立即更新成功状态
                    
                    AppConfig.LOGGER.error("查询并更新NFT {} 的BSN状态成功{}", nftt.getLong("id"), searchObject);
                }
                // 如果 status 是其他值，可能表示正在处理中，不更新 bsn_token_id
            } catch (Exception e) {
                // 记录错误日志，但通常不应该影响整个列表的返回
                AppConfig.LOGGER.error("查询并更新NFT {} 的BSN状态时出现问题：{}", nftt.getLong("id"), e.getMessage(), e);
                // 这里可以选择不throw，或者throw RuntimeException让上层捕获
                // 如果是服务故障，可能需要全局捕获并告警
            }
        }
    }
}
