package com.lingniu.ingest.protocol.jt808.handler;

import com.lingniu.ingest.api.ProtocolId;
import com.lingniu.ingest.api.annotation.AsyncBatch;
import com.lingniu.ingest.api.annotation.EventEmit;
import com.lingniu.ingest.api.annotation.MessageMapping;
import com.lingniu.ingest.api.annotation.ProtocolHandler;
import com.lingniu.ingest.api.annotation.RateLimited;
import com.lingniu.ingest.api.event.VehicleEvent;
import com.lingniu.ingest.protocol.jt808.mapper.Jt808EventMapper;
import com.lingniu.ingest.protocol.jt808.model.Jt808Body;
import com.lingniu.ingest.protocol.jt808.model.Jt808Message;
import com.lingniu.ingest.protocol.jt808.model.Jt808MessageId;

import java.util.ArrayList;
import java.util.List;

/**
 * JT808 示例 Handler：演示注解驱动的路由与事件产出。
 *
 * <p>位置上报使用 {@code @AsyncBatch} 批量聚合（对标旧代码里的 4000/1s 批量落库）。
 * 带 {@code @AsyncBatch} 的方法签名约定为 {@code List<PayloadType>}。
 */
@ProtocolHandler(protocol = ProtocolId.JT808)
public class Jt808LocationHandler {

    private final Jt808EventMapper mapper;

    public Jt808LocationHandler(Jt808EventMapper mapper) {
        this.mapper = mapper;
    }

    @MessageMapping(command = {
            Jt808MessageId.TERMINAL_LOCATION,
            Jt808MessageId.TERMINAL_LOCATION_BATCH
    }, desc = "位置信息汇报（批量）")
    @RateLimited(perVin = 20)
    @AsyncBatch(size = 4000, waitMs = 1000, poolSize = 2)
    @EventEmit(VehicleEvent.Location.class)
    public List<VehicleEvent> onLocationBatch(List<Jt808Message> batch) {
        List<VehicleEvent> all = new ArrayList<>(batch.size());
        for (Jt808Message msg : batch) {
            all.addAll(mapper.toEvents(msg));
        }
        return all;
    }

    @MessageMapping(command = {Jt808MessageId.TERMINAL_REGISTER, Jt808MessageId.TERMINAL_AUTH}, desc = "注册/鉴权")
    @EventEmit(VehicleEvent.Login.class)
    public List<VehicleEvent> onLogin(Jt808Message msg) {
        return mapper.toEvents(msg);
    }

    @MessageMapping(command = {
            Jt808MessageId.TERMINAL_UNREGISTER,
            Jt808MessageId.TERMINAL_PARAMS_REPORT,
            Jt808MessageId.TERMINAL_ATTRS_REPORT,
            Jt808MessageId.TERMINAL_MEDIA_EVENT,
            Jt808MessageId.TERMINAL_MEDIA_UPLOAD,
            Jt808MessageId.TERMINAL_PASSTHROUGH
    }, desc = "终端状态/属性/多媒体/透传")
    @EventEmit({VehicleEvent.Logout.class, VehicleEvent.Login.class, VehicleEvent.MediaMeta.class, VehicleEvent.Passthrough.class})
    public List<VehicleEvent> onExtended(Jt808Message msg) {
        return mapper.toEvents(msg);
    }

    @MessageMapping(command = Jt808MessageId.TERMINAL_HEARTBEAT, desc = "心跳")
    @EventEmit(VehicleEvent.Heartbeat.class)
    public List<VehicleEvent> onHeartbeat(Jt808Message msg) {
        return mapper.toEvents(msg);
    }

    @MessageMapping(desc = "未解析 JT808 上行兜底透传")
    @EventEmit(VehicleEvent.Passthrough.class)
    public List<VehicleEvent> onRaw(Jt808Message msg) {
        if (!(msg.body() instanceof Jt808Body.Raw) && !(msg.body() instanceof Jt808Body.Malformed)) {
            return List.of();
        }
        return mapper.toEvents(msg);
    }
}
