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

import java.util.LinkedHashMap;
import java.util.Map;

public final class Jt808LocationFlagInfo {

    private static final String[] ALARM_BITS = {
            "emergency",
            "overspeed",
            "fatigue_driving",
            "warning",
            "gnss_module_fault",
            "gnss_antenna_disconnected",
            "gnss_antenna_short_circuit",
            "terminal_main_power_undervoltage",
            "terminal_main_power_lost",
            "display_fault",
            "tts_fault",
            "camera_fault",
            "transport_ic_card_fault",
            "overspeed_warning",
            "fatigue_driving_warning",
            "prohibited_driving",
            null,
            null,
            "daily_driving_timeout",
            "overtime_parking",
            "area_in_out",
            "route_in_out",
            "route_time_abnormal",
            "route_deviation",
            "vss_fault",
            "fuel_abnormal",
            "stolen",
            "illegal_ignition",
            "illegal_displacement",
            "collision_rollover",
            "rollover_warning"
    };

    private Jt808LocationFlagInfo() {
    }

    public static Map<String, String> decodeAlarm(long alarmFlag, String prefix) {
        Map<String, String> out = new LinkedHashMap<>();
        String p = prefix == null ? "" : prefix;
        for (int i = 0; i < ALARM_BITS.length; i++) {
            String name = ALARM_BITS[i];
            if (name != null) {
                out.put(p + name, Boolean.toString(bit(alarmFlag, i)));
            }
        }
        return Map.copyOf(out);
    }

    public static Map<String, String> decodeStatus(long statusFlag, String prefix) {
        Map<String, String> out = new LinkedHashMap<>();
        String p = prefix == null ? "" : prefix;
        out.put(p + "acc_on", Boolean.toString(bit(statusFlag, 0)));
        out.put(p + "positioned", Boolean.toString(bit(statusFlag, 1)));
        out.put(p + "south_latitude", Boolean.toString(bit(statusFlag, 2)));
        out.put(p + "west_longitude", Boolean.toString(bit(statusFlag, 3)));
        out.put(p + "out_of_service", Boolean.toString(bit(statusFlag, 4)));
        out.put(p + "encrypted", Boolean.toString(bit(statusFlag, 5)));
        out.put(p + "forward_collision_warning", Boolean.toString(bit(statusFlag, 6)));
        out.put(p + "lane_departure_warning", Boolean.toString(bit(statusFlag, 7)));
        out.put(p + "load_status", loadStatus(statusFlag));
        out.put(p + "fuel_circuit_cut", Boolean.toString(bit(statusFlag, 10)));
        out.put(p + "electric_circuit_cut", Boolean.toString(bit(statusFlag, 11)));
        out.put(p + "door_locked", Boolean.toString(bit(statusFlag, 12)));
        out.put(p + "door1_open", Boolean.toString(bit(statusFlag, 13)));
        out.put(p + "door2_open", Boolean.toString(bit(statusFlag, 14)));
        out.put(p + "door3_open", Boolean.toString(bit(statusFlag, 15)));
        out.put(p + "door4_open", Boolean.toString(bit(statusFlag, 16)));
        out.put(p + "door5_open", Boolean.toString(bit(statusFlag, 17)));
        out.put(p + "gps_used", Boolean.toString(bit(statusFlag, 18)));
        out.put(p + "beidou_used", Boolean.toString(bit(statusFlag, 19)));
        out.put(p + "glonass_used", Boolean.toString(bit(statusFlag, 20)));
        out.put(p + "galileo_used", Boolean.toString(bit(statusFlag, 21)));
        out.put(p + "moving", Boolean.toString(bit(statusFlag, 22)));
        return Map.copyOf(out);
    }

    private static String loadStatus(long statusFlag) {
        int code = (int) ((statusFlag >>> 8) & 0x03);
        return switch (code) {
            case 0 -> "EMPTY";
            case 1 -> "HALF_LOADED";
            case 2 -> "RESERVED";
            case 3 -> "FULL";
            default -> "UNKNOWN";
        };
    }

    private static boolean bit(long raw, int bit) {
        return ((raw >>> bit) & 1L) == 1L;
    }
}
