<script lang="ts">
  import { onMount, onDestroy, createEventDispatcher } from 'svelte';
  import { MudConnection } from '$lib/connection/MudConnection';
  import { GmcpHandler } from '$lib/gmcp/GmcpHandler';
  import { TriggerSystem } from '$lib/triggers/TriggerSystem';
  import { AccessibilityManager } from '$lib/accessibility/AccessibilityManager';
  import { 
    connections, 
    connectionStatus, 
    activeProfileId, 
    activeProfile, 
    addToOutputHistory, 
    updateGmcpData,
    accessibilitySettings,
    uiSettings
  } from '$lib/stores/mudStore';
  import { get } from 'svelte/store';
  
  const dispatch = createEventDispatcher();
  
  // Props
  export let profileId: string;
  export let autoConnect = false;
  
  // Local state
  let connection: MudConnection | null = null;
  let gmcpHandler: GmcpHandler | null = null;
  let triggerSystem: TriggerSystem | null = null;
  let accessibilityManager: AccessibilityManager | null = null;
  
  /**
   * Handle keyboard events for speech control
   */
  function handleKeyDown(event: KeyboardEvent): void {
    // Control key stops speech - the key code for Control is 17
    if (event.key === 'Control' || event.ctrlKey || event.keyCode === 17) {
      // Stop propagation to ensure no other handlers interfere
      event.stopPropagation();
      
      if (accessibilityManager && accessibilityManager.isSpeaking()) {
        console.log('Control key pressed - stopping speech');
        accessibilityManager.stopSpeech();
      }
    }
    
    // Enter key stops speech if the setting is enabled
    if ((event.key === 'Enter' || event.keyCode === 13) && $accessibilitySettings.interruptSpeechOnEnter) {
      if (accessibilityManager && accessibilityManager.isSpeaking()) {
        console.log('Enter key pressed - interrupting speech');
        accessibilityManager.stopSpeech();
      }
    }
  }
  
  onMount(() => {
    // Initialize components
    initializeComponents();
    
    // Set up keyboard listener for speech control - use capture phase and make it top-level
    document.addEventListener('keydown', handleKeyDown, true); // Using document instead of window
    
    // Auto-connect if enabled
    if (autoConnect) {
      console.log('Auto-connecting profile:', profileId);
      connect();
    }
    
    // Update connection status - ensure UI shows status as 'disconnected' at start
    connectionStatus.update(statuses => ({
      ...statuses,
      [profileId]: 'disconnected'
    }));
  });
  
  onDestroy(() => {
    // Remove keyboard listener
    document.removeEventListener('keydown', handleKeyDown, true); // Match document and capture phase
    
    // Clean up connection
    if (connection) {
      connection.disconnect();
    }
    
    // Remove from connections store
    connections.update(conns => {
      const newConns = { ...conns };
      delete newConns[profileId];
      return newConns;
    });
    
    // Update connection status
    connectionStatus.update(statuses => {
      const newStatuses = { ...statuses };
      delete newStatuses[profileId];
      return newStatuses;
    });
  });
  
  /**
   * Initialize connection components
   */
  function initializeComponents() {
    // Create GMCP handler
    gmcpHandler = new GmcpHandler();
    
    // Create trigger system
    triggerSystem = new TriggerSystem();
    
    // Create accessibility manager
    accessibilityManager = new AccessibilityManager();
    
    // Set up event listeners
    setupEventListeners();
  }
  
  /**
   * Set up event listeners for components
   */
  function setupEventListeners() {
    if (!gmcpHandler || !triggerSystem || !accessibilityManager) return;
    
    // GMCP handler events
    gmcpHandler.on('gmcp', (module, data) => {
      updateGmcpData(module, data);
    });
    
    gmcpHandler.on('sendGmcp', (module, data) => {
      if (connection) {
        connection.sendGmcp(module, data);
      }
    });
    
    gmcpHandler.on('playSound', (url, volume, loop) => {
      dispatch('playSound', { url, volume, loop });
    });
    
    // Trigger system events
    triggerSystem.on('sendText', (text) => {
      if (connection) {
        connection.send(text);
      }
    });
    
    triggerSystem.on('highlight', (text, pattern, color, isRegex) => {
      dispatch('highlight', { text, pattern, color, isRegex });
    });
    
    // Set up TTS subscription - use direct subscription to avoid circular updates
    const unsubscribeTts = accessibilitySettings.subscribe(settings => {
      try {
        // Set speech enabled directly based on the store value
        if (accessibilityManager) {
          console.log('Setting TTS from store:', settings.textToSpeech);
          accessibilityManager.setSpeechEnabled(settings.textToSpeech);
          
          // Update speech options when settings change
          accessibilityManager.updateSpeechOptions({
            rate: settings.speechRate,
            pitch: settings.speechPitch,
            volume: settings.speechVolume
          });
        }
      } catch (error) {
        console.error('Error updating TTS setting:', error);
      }
    });
    
    // Set up only GMCP debugging subscription
    let previousGmcpDebug = $uiSettings.debugGmcp;
    const unsubscribeUiSettings = uiSettings.subscribe(settings => {
      if (settings.debugGmcp !== previousGmcpDebug) {
        previousGmcpDebug = settings.debugGmcp;
      }
    });
    
    // Clean up subscriptions on component destruction
    onDestroy(() => {
      unsubscribeUiSettings();
      unsubscribeTts();
    });
  }
  
  /**
   * Connect to the MUD server
   */
  export function connect() {
    const profile = get(activeProfile);
    console.log('Connecting to profile:', profile);
    
    if (!profile) {
      addToOutputHistory('Error: No active profile selected.');
      console.error('No active profile selected');
      return;
    }
    
    // Update connection status
    connectionStatus.update(statuses => ({
      ...statuses,
      [profileId]: 'connecting'
    }));
    
    try {
      addToOutputHistory(`Connecting to ${profile.host}:${profile.port}...`);
      
      // Create connection
      connection = new MudConnection({
        host: profile.host,
        port: profile.port,
        useSSL: profile.useSSL,
        gmcpHandler: gmcpHandler || undefined
      });
      
      console.log('Connection object created:', connection);
      
      // Set up connection event listeners
      connection.on('connected', handleConnected);
      connection.on('disconnected', handleDisconnected);
      connection.on('error', handleError);
      connection.on('received', handleReceived);
      connection.on('sent', handleSent);
      
      // Add to connections store
      connections.update(conns => ({
        ...conns,
        [profileId]: connection as MudConnection
      }));
      
      // Connect
      connection.connect();
    } catch (error) {
      console.error('Failed to connect:', error);
      
      connectionStatus.update(statuses => ({
        ...statuses,
        [profileId]: 'error'
      }));
      
      addToOutputHistory(`Error connecting to ${profile.host}:${profile.port} - ${error}`);
    }
  }
  
  /**
   * Disconnect from the MUD server
   */
  export function disconnect() {
    if (connection) {
      connection.disconnect();
    }
  }
  
  /**
   * Handle connection established
   */
  function handleConnected() {
    const profile = get(activeProfile);
    
    connectionStatus.update(statuses => ({
      ...statuses,
      [profileId]: 'connected'
    }));
    
    addToOutputHistory(`Connected to ${profile?.host}:${profile?.port}`);
    
    // Handle auto-login if enabled
    if (profile?.autoLogin?.enabled) {
      setTimeout(() => {
        // Send username
        if (profile.autoLogin?.username) {
          if (connection) connection.send(profile.autoLogin.username);
        }
        
        // Send password after a delay
        if (profile.autoLogin?.password) {
          setTimeout(() => {
            if (connection) connection.send(profile.autoLogin?.password || '');
            
            // Send additional commands
            if (profile.autoLogin?.commands && profile.autoLogin.commands.length > 0) {
              let delay = 500;
              profile.autoLogin.commands.forEach((cmd) => {
                setTimeout(() => {
                  if (connection) connection.send(cmd);
                }, delay);
                delay += 500;
              });
            }
          }, 1000);
        }
      }, 1000);
    }
    
    dispatch('connected');
  }
  
  /**
   * Handle connection closed
   */
  function handleDisconnected() {
    connectionStatus.update(statuses => ({
      ...statuses,
      [profileId]: 'disconnected'
    }));
    
    addToOutputHistory('Disconnected from server.');
    dispatch('disconnected');
  }
  
  /**
   * Handle connection error
   */
  function handleError(error: any) {
    connectionStatus.update(statuses => ({
      ...statuses,
      [profileId]: 'error'
    }));
    
    // Format the error message for display
    const errorMessage = typeof error === 'object' ? 
      (error.message || JSON.stringify(error)) : 
      String(error);
    
    addToOutputHistory(`Connection error: ${errorMessage}`, false, [
      { pattern: 'Connection error', color: '#ff5555', isRegex: false }
    ]);
    
    dispatch('error', { error });
  }
  
  /**
   * Handle received data
   */
  function handleReceived(text: string) {
    // Add to output history first
    addToOutputHistory(text);
    
    // Process triggers with safe error handling
    if (triggerSystem) {
      try {
        triggerSystem.processTriggers(text);
      } catch (error) {
        console.error('Error processing triggers:', error);
      }
    }
    
    // Try to use text-to-speech if enabled
    if (accessibilityManager && $accessibilitySettings.textToSpeech) {
      // Use a small timeout to avoid UI blocking
      setTimeout(() => {
        try {
          accessibilityManager.speak(text);
        } catch (error) {
          console.error('Error using text-to-speech:', error);
        }
      }, 10);
    }
    
    dispatch('received', { text });
  }
  
  /**
   * Handle sent data
   */
  function handleSent(text: string) {
    dispatch('sent', { text });
  }
</script>

{#if $connectionStatus[profileId]}
  <div class="mud-connection-status" role="status" aria-live="polite">
    <div class="status-indicator status-{$connectionStatus[profileId]}" aria-hidden="true"></div>
    <span>Server status: {$connectionStatus[profileId]}</span>
    {#if $connectionStatus[profileId] === 'error'}
      <span class="sr-only">There was an error connecting to the MUD server. Please check your settings and try again.</span>
    {/if}
  </div>
{/if}

<style>
  .mud-connection-status {
    display: flex;
    align-items: center;
    padding: 5px;
    font-size: 0.9em;
  }
  
  .status-indicator {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 5px;
  }
  
  .status-connected {
    background-color: #50fa7b;
  }
  
  .status-connecting {
    background-color: #f1fa8c;
  }
  
  .status-disconnected {
    background-color: #999;
  }
  
  .status-error {
    background-color: #ff5555;
  }
  
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
  }
</style>
