// src/services/MqttService.js
import mqtt from 'mqtt';
import { ref } from 'vue';

const client = ref(null);
const connectionStatus = ref('disconnected');
const error = ref(null);
const receivedMessages = ref([]); // For debugging
const MQTT_TOPIC_GAME = 'game';

let generalMessageHandlerCallback = null; // For App.vue to handle game commands

// --- MQTT Character Capture State ---
const isCapturingMqttChar = ref(false);
const mqttCharCaptureCallback = ref(null); // Function to call when a char is captured

const startMqttCharCapture = (onCapturedCallback) => {
  console.log("MQTT Service: Starting character capture mode.");
  isCapturingMqttChar.value = true;
  mqttCharCaptureCallback.value = onCapturedCallback;
};

const stopMqttCharCapture = () => {
  console.log("MQTT Service: Stopping character capture mode.");
  isCapturingMqttChar.value = false;
  mqttCharCaptureCallback.value = null;
};
// --- End MQTT Character Capture State ---

const connect = async (brokerUrl = 'ws://localhost:9001') => {
  // ... (existing connect logic)
  if (client.value && client.value.connected) { return; }
  if (connectionStatus.value === 'connecting') { return; }
  console.log(`MQTT: Attempting to connect to ${brokerUrl}...`);
  connectionStatus.value = 'connecting';
  error.value = null;
  let fullBrokerUrl = brokerUrl;
    if (!brokerUrl.startsWith('ws://') && !brokerUrl.startsWith('wss://')) {
        if (brokerUrl.includes(':1883')) {
            fullBrokerUrl = `ws://${brokerUrl}`;
        } else if (!brokerUrl.includes(':')) {
            fullBrokerUrl = `ws://${brokerUrl}:9001`;
        } else {
             fullBrokerUrl = `ws://${brokerUrl}`;
        }
    }

  try {
    const connectFn = typeof mqtt === 'function' ? mqtt : (mqtt.connect || (mqtt.default && mqtt.default.connect));
    if (typeof connectFn !== 'function') {
      throw new Error("MQTT connect function not found.");
    }
    client.value = connectFn(fullBrokerUrl, {
        reconnectPeriod: 5000,
        connectTimeout: 10000,
    });

    client.value.on('connect', () => {
      console.log('MQTT: Connected!');
      connectionStatus.value = 'connected';
      error.value = null;
      client.value.subscribe(MQTT_TOPIC_GAME, (err) => {
        if (!err) { console.log(`MQTT: Subscribed to "${MQTT_TOPIC_GAME}"`); }
        else { 
          console.error('MQTT: Subscr. error:', err); 
          connectionStatus.value = 'error'; error.value = 'Subscription failed.';
        }
      });
    });

    client.value.on('message', (topic, message) => {
      const msgString = message.toString();
      const char = msgString.charAt(0).toLowerCase(); // Process as lowercase single char
      console.log(`MQTT: Received on "${topic}": '${msgString}' -> processed char: '${char}'`);
      receivedMessages.value.push({ topic, message: msgString, time: new Date() });

      if (topic === MQTT_TOPIC_GAME && char.length === 1) {
        if (isCapturingMqttChar.value && mqttCharCaptureCallback.value) {
          console.log(`MQTT Service: Captured char '${char}' for registration.`);
          mqttCharCaptureCallback.value(char); // Pass char to the specific capture handler
          stopMqttCharCapture(); // Stop capture mode after one char
        } else if (generalMessageHandlerCallback) {
          // Normal message processing if not in capture mode
          generalMessageHandlerCallback(char);
        }
      }
    });

    client.value.on('error', (err) => { /* ... existing error handling ... */ 
        console.error('MQTT: Connection error:', err);
        connectionStatus.value = 'error';
        error.value = err.message || 'Connection error';
    });
    client.value.on('reconnect', () => { /* ... existing reconnect handling ... */ 
        console.log('MQTT: Reconnecting...');
        connectionStatus.value = 'connecting';
    });
    client.value.on('offline', () => { /* ... existing offline handling ... */ 
        console.log('MQTT: Client offline.');
    });
    client.value.on('close', () => { /* ... existing close handling ... */ 
        console.log('MQTT: Connection closed.');
        if (connectionStatus.value !== 'error' && connectionStatus.value !== 'connecting') { 
            connectionStatus.value = 'disconnected';
        }
    });

  } catch (err) { /* ... existing catch ... */ 
    console.error('MQTT: Setup error during connect call:', err);
    connectionStatus.value = 'error';
    error.value = err.message || 'Setup failed.';
    if(client.value && typeof client.value.end === 'function') client.value.end(true);
    client.value = null;
  }
};

const disconnect = () => {
  if (client.value) {
    console.log('MQTT: Disconnecting/Stopping connection attempt...');
    // Set status immediately to give user feedback, 'close' event will confirm
    // but if it was 'connecting', it might not emit 'close' if it never truly connected.
    const wasConnecting = connectionStatus.value === 'connecting';
    
    client.value.end(true, () => { // true forces close and stops reconnect attempts
      console.log('MQTT: client.end() callback executed.');
      // The 'close' event listener on the client should handle final cleanup
      // like setting client.value = null and connectionStatus.value = 'disconnected'.
      // If it was just 'connecting' and never connected, 'close' might not fire reliably.
      if (wasConnecting && connectionStatus.value !== 'disconnected') {
          connectionStatus.value = 'disconnected';
          client.value = null; // Ensure cleanup if 'close' doesn't fire from 'connecting' state
      }
    });
    // If it was 'connecting', we might want to immediately reflect disconnected state
    // as 'end(true)' stops further attempts.
    if (wasConnecting) {
        connectionStatus.value = 'disconnected'; 
        // Note: client.value will be fully nulled on the 'close' event or after end() callback.
    }

  } else {
    console.log('MQTT: No active client to disconnect.');
    connectionStatus.value = 'disconnected'; // Ensure status is correct
  }
};

const setGeneralMessageHandler = (handler) => { // Renamed for clarity
  generalMessageHandlerCallback = handler;
};

export const MqttService = {
  connect,
  disconnect,
  setGeneralMessageHandler, // Use this for App.vue game commands
  connectionStatus,
  error,
  receivedMessages,
  MQTT_TOPIC_GAME,
  getClient: () => client.value,
  // New methods for capture mode
  startMqttCharCapture,
  stopMqttCharCapture,
  isCapturingMqttChar // Expose reactive state if needed elsewhere, though not directly used by components
};