package modules.withdraw;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Db;
import common.model.*;
import common.utils.hyg.HygSDK;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

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

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

    private void flushWithdrawState(List<Withdraw> withdrawList) throws InterruptedException {
        // 未给用户转账的进行转账
        for (Withdraw w : withdrawList) {
            // 1秒最多检查1个提现请求，防止超频
            Thread.sleep(TimeUnit.SECONDS.toMillis(1));

            // 使用事务锁定
            Db.tx(() -> {
                User user = User.dao.findFirst("SELECT * FROM t_user WHERE id=? FOR UPDATE", w.getUserId());

                try {
                    JSONObject hygRst = HygSDK.signalQuery(w.getWithdrawSn());
                    
                    // 失败的等能获取再说
                    if (!hygRst.getString("statusCode").equals("000000")) {
                        LOGGER.error("请求提现订单时失败{}", hygRst);
                        
                        return true;
                    }
                    
                    // 获取真实结构体
                    JSONObject data = hygRst.getJSONObject("data");
                    
                    int distributeStatus = data.getInteger("distributeStatus"); // 状态码
                    String remark = data.getString("remark"); // 备注

                    // 下发状态	
                    // 9-待验证，
                    // 10-验证成功，
                    // 20-验证失败，
                    // 30-已取消,
                    // 40-待打款，
                    // 50-打款中，
                    // 60-打款成功，
                    // 70-打款失败,
                    // 75-已退款,
                    // 80-退票中,
                    // 90-已退票
                    
                    // 这些状态视为失败的
                    if (distributeStatus == 20 
                            || distributeStatus == 30 
                            || distributeStatus == 70 
                            || distributeStatus == 75 
                            || distributeStatus == 80 
                            || distributeStatus == 90) {
                        // 1. 处理单据的状态
                        w.setStatus(40);
                        w.setHygOrigin(hygRst.toString());
                        w.setReason(remark);
                        w.setUpdateTime(System.currentTimeMillis());
                        w.update();
                        
                        // 2. 处理用户的状态
                        user.setBalance(user.getBalance() + w.getAmount());
                        user.update();

                        // 3. 资金流水处理
                        BalanceLog l = new BalanceLog();
                        l.set("create_time", System.currentTimeMillis());
                        l.set("is_deleted", 0);
                        l.set("description", "提现失败退还，慧用工原因：" + remark); // 描述中带上百分比
                        l.set("amount", w.getAmount());
                        l.set("user_id", user.getLong("id"));
                        l.save();

                        LOGGER.info("慧用工提现失败：{}", w);
                        
                        return true;
                    }
                    
                    // 这个逻辑视为打款成功的
                    if (distributeStatus == 60) {
                        w.setStatus(30);
                        w.setHygOrigin(hygRst.toString());
                        w.update();
                        
                        LOGGER.info("慧用工提现已成功：{}", w);
                        
                        return true;
                    }
                } catch (Exception e) {
                    LOGGER.error("提现状态获取失败：{}", e.getMessage());
                }
                
                return true;
            });
        }
    }
}
