// mqttService.js
import mqtt from 'mqtt';

const mqttUrl = `${import.meta.env.VITE_MQTT_SERVER ?? 'ws://localhost:1884'}`;
const topics = [
    'PIU_COD/AIR_DRYER/OVERVIEW',
    'PIU_COD/AIR_DRYER/AIR_DRYER_A',
    'PIU_COD/AIR_DRYER/AIR_DRYER_B',
    'PIU_COD/AIR_DRYER/AIR_DRYER_C',
    'PIU_COD/COMPRESSOR/OVERVIEW',
    'PIU_COD/COMPRESSOR/COMPRESSOR_A',
    'PIU_COD/COMPRESSOR/COMPRESSOR_B',
    'PIU_COD/COMPRESSOR/COMPRESSOR_C',
    'PIU_COD/ERROR_CODE/SIM',
];
const options = {
    keepalive: 30,
    clientId: 'react_mqtt_' + Math.random().toString(16).substr(2, 8),
    protocolId: 'MQTT',
    protocolVersion: 4,
    clean: true,
    reconnectPeriod: 1000,
    connectTimeout: 30 * 1000,
    username: `${import.meta.env.VITE_MQTT_USERNAME ?? ''}`, // jika ada
    password: `${import.meta.env.VITE_MQTT_PASSWORD ?? ''}`, // jika ada
};

const client = mqtt.connect(mqttUrl, options);

// Track connection status
let isConnected = false;

client.on('connect', () => {
    console.log('MQTT Connected');
    isConnected = true;

    // Subscribe default topic
    client.subscribe(topics, (err) => {
        if (err) console.error('Subscribe error:', err);
        else console.log(`Subscribed to topics: ${topics.join(', ')}`);
    });
});

client.on('error', (err) => {
    console.error('Connection error: ', err);
    client.end();
});

client.on('close', () => {
    console.log('MQTT Disconnected');
    isConnected = false;
});

/**
 * Publish message to MQTT
 * @param {string} topic
 * @param {string} message
 */
const publishMessage = (topic, message) => {
    if (client && isConnected && message.trim() !== '') {
        client.publish(topic, message);
    } else {
        console.warn('MQTT not connected or message empty');
    }
};

/**
 * Listen to incoming messages
 * @param {function} callback - Function(topic, message)
 */
const listenMessage = (callback) => {
    client.on('message', (topic, message) => {
        callback(topic, message.toString());
    });
};

const colorIds = ['c_1023', 'c_2023', 'c_2023'];
const StatusColor = (el, num) => {
    switch (num) {
        case 1:
            el.style.fill = 'orange';
            break;
        case 2:
            el.style.fill = 'rgb(7,250,14)';
            break;
        default:
            el.style.fill = 'rgb(216,216,216)';
    }
};

const dryerIds = ['c_4018', 'c_4021', 'c_5018', 'c_5021', 'c_6018', 'c_6021'];
const handleBoolean = (svg, el, value) => {
    if (!dryerIds.includes(el.id)) {
        el.style.display = value ? '' : 'none';
        return;
    }

    const i = dryerIds.indexOf(el.id);
    const id1 = dryerIds[i - (i % 2)];
    const id2 = dryerIds[i - (i % 2) + 1];

    const els1 = svg.querySelectorAll(`#${id1}`);
    const els2 = svg.querySelectorAll(`#${id2}`);

    if (!els1 || !els2) return;

    els1.forEach(el => {
        el.style.fill = value ? 'rgb(216,216,216)' : 'rgb(255, 204, 63)';
    });
    els2.forEach(el => {
        el.style.fill = value ? 'rgb(255, 204, 63)' : 'rgb(216,216,216)';
    });
};

const handleNumber = (el, value) => {
    const num = Number(value);

    if (colorIds.includes(el.id)) {
        StatusColor(el, num);
    } else {
        el.textContent = num.toFixed(2);
    }
};

const handleOther = (el, value) => {
    el.textContent = value;
};

const setValSvg = (listenTopic, svg) => {
    client.on('message', (topic, message) => {
        if (topic === listenTopic) {
            const objChanel = JSON.parse(message);

            Object.entries(objChanel).forEach(([key, value]) => {
                const el = svg.getElementById(key);

                if (!el) return;
                // else if (el.id === 'c_2014' || el.id === 'c_2024') {
                //     el.setAttribute('text-anchor', 'middle');
                //     el.setAttribute('x', '10%');
                // }
                if (typeof value === 'boolean') {
                    handleBoolean(svg, el, value);
                } else if (!isNaN(value)) {
                    handleNumber(el, value);
                } else {
                    handleOther(el, value);
                }
            });
            const target = svg.querySelector('text[x="225.25"][y="537.752"]');
            if (target) target.remove();
        }
    });
};

// === NOTIFICATION LISTENER ===
const notifListeners = [];

const onNotifUpdate = (callback) => {
    notifListeners.push(callback);
};

client.on('message', (topic, message) => {
    if (topic === import.meta.env.VITE_MQTT_TOPIC_COD) {
        try {
            const payload = JSON.parse(message.toString());
            notifListeners.forEach((cb) => cb(payload));
        } catch (err) {
            console.error('Invalid notif payload', err);
        }
    }
});

export { publishMessage, listenMessage, setValSvg, onNotifUpdate };
