package com.kym.service.awoara.event.handle;

import com.kym.entity.WashDevice;
import com.kym.entity.WashOrder;
import com.kym.entity.awoara.DeviceStateObject;
import com.kym.entity.awoara.MessageBody;
import com.kym.entity.awoara.OrderInfo;
import com.kym.service.OrderSettlementService;
import com.kym.service.WashDeviceService;
import com.kym.service.WashOrderService;
import com.kym.service.awoara.AwoaraService;
import lombok.extern.slf4j.Slf4j;

/**
 * 设备启动事件处理
 *
 * @author skyline
 */
@Slf4j
public class BootEventHandler implements AwoaraEventHandler<DeviceStateObject> {

    private final WashDeviceService washDeviceService;
    private final WashOrderService washOrderService;
    private final AwoaraService awoaraService;
    private final OrderSettlementService orderSettlementService;

    public BootEventHandler(WashDeviceService washDeviceService,
                            WashOrderService washOrderService,
                            AwoaraService awoaraService,
                            OrderSettlementService orderSettlementService) {
        this.washDeviceService = washDeviceService;
        this.washOrderService = washOrderService;
        this.awoaraService = awoaraService;
        this.orderSettlementService = orderSettlementService;
    }

    @Override
    public void handle(MessageBody<DeviceStateObject> message) {
        log.info("BootEventHandler: {}", message);

        var topic = message.getTopic().split("/");
        var productKey = topic[1];
        var deviceName = topic[2];

        var device = washDeviceService.lambdaQuery()
                .eq(WashDevice::getProductKey, productKey)
                .eq(WashDevice::getDeviceName, deviceName)
                .one();

        if (device == null) {
            log.warn("BootEventHandler: 未找到设备 productKey={}, deviceName={}", productKey, deviceName);
            return;
        }

        // 更新设备状态
        washDeviceService.lambdaUpdate()
                .set(WashDevice::getState, message.getPayload().getData().getDevice_state().getState())
                .eq(WashDevice::getId, device.getId())
                .update();

        // 查询该设备下所有未支付订单，尝试对账结算
        var orderList = washOrderService.lambdaQuery()
                .eq(WashOrder::getProductKey, productKey)
                .eq(WashOrder::getDeviceName, deviceName)
                .eq(WashOrder::getPayStatus, WashOrder.PAY_STATUS_未支付)
                .list();

        if (orderList.isEmpty()) {
            return;
        }

        log.info("BootEventHandler: 设备 {}/{} 重启后发现 {} 个未支付订单", productKey, deviceName, orderList.size());

        for (WashOrder order : orderList) {
            try {
                reconcileOrder(order, productKey, deviceName);
            } catch (Exception e) {
                log.error("BootEventHandler: 订单 {} 对账异常", order.getOrderId(), e);
            }
        }
    }

    private void reconcileOrder(WashOrder order, String productKey, String deviceName) {
        try {
            OrderInfo orderInfo = awoaraService.queryOrder(productKey, deviceName, order.getOrderId());

            if (orderInfo != null && orderInfo.getClose_type() != null && !orderInfo.getClose_type().isEmpty()) {
                log.info("BootEventHandler: 订单 {} 设备已关闭，执行结算", order.getOrderId());
                orderSettlementService.settleOrder(order, orderInfo);
                return;
            }

            if (orderInfo != null && (orderInfo.getClose_type() == null || orderInfo.getClose_type().isEmpty())) {
                log.info("BootEventHandler: 订单 {} 设备仍在进行中，跳过", order.getOrderId());
                return;
            }

            // 设备上查不到该订单（2G版本重启后无法查询历史订单）
            log.warn("BootEventHandler: 订单 {} 在设备上未找到，标记待定时对账", order.getOrderId());
            washOrderService.lambdaUpdate()
                    .set(WashOrder::getStopReason, "设备重启，订单在设备上未找到，待定时对账")
                    .eq(WashOrder::getId, order.getId())
                    .update();

        } catch (Exception e) {
            log.warn("BootEventHandler: 订单 {} 查询设备失败: {}", order.getOrderId(), e.getMessage());
            washOrderService.lambdaUpdate()
                    .set(WashOrder::getStopReason, "设备重启，查询订单失败：" + e.getMessage())
                    .eq(WashOrder::getId, order.getId())
                    .update();
        }
    }
}
