(function() {
  function tKey(key) {
    return typeof t === 'function' ? t(key) : key;
  }

  function currentProtocolCapabilities() {
    return window.CrankWizardState.currentProtocolCapabilities();
  }

  function text(id) {
    var element = document.getElementById(id);
    return element ? String(element.value || '').trim() : '';
  }

  function set(id, value) {
    var element = document.getElementById(id);
    if (element) {
      element.value = value || '';
    }
  }

  function number(id) {
    var value = text(id);
    if (!value) return null;
    var parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
  }

  function lines(id) {
    var value = text(id);
    return value
      ? value.split('\n').map(function(item) { return item.trim(); }).filter(Boolean)
      : [];
  }

  function checked(id) {
    var element = document.getElementById(id);
    return !!(element && element.checked);
  }

  function selectedMode() {
    return text('streaming-mode') || 'unary';
  }

  function transportOptionsForMode(mode) {
    var capabilities = currentProtocolCapabilities();
    var behaviors = (capabilities.supports_transport_behaviors || []).slice();
    if (mode === 'unary') return behaviors.filter(function(value) { return value === 'request_response'; });
    if (mode === 'window') return behaviors.filter(function(value) {
      return value === 'request_response' || value === 'server_stream';
    });
    if (mode === 'session') return behaviors.filter(function(value) {
      return value === 'server_stream' || value === 'stateful_session';
    });
    if (mode === 'async_job') return behaviors.filter(function(value) {
      return value === 'deferred_result';
    });
    return behaviors;
  }

  function modeOptionsForProtocol() {
    var capabilities = currentProtocolCapabilities();
    return (capabilities.supports_execution_modes || ['unary']).filter(function(mode) {
      return transportOptionsForMode(mode).length > 0 || mode === 'unary';
    });
  }

  function updateStreamingTransportOptions(preferredValue) {
    var element = document.getElementById('streaming-transport-behavior');
    if (!element) return;
    var options = transportOptionsForMode(selectedMode());
    element.innerHTML = '';
    options.forEach(function(value) {
      var option = document.createElement('option');
      option.value = value;
      option.textContent = tKey('wizard.streaming.transport.' + value);
      element.appendChild(option);
    });
    if (preferredValue && options.indexOf(preferredValue) >= 0) {
      element.value = preferredValue;
    } else if (options.length) {
      element.value = options[0];
    }
  }

  function updateStreamingModeOptions(preferredValue) {
    var element = document.getElementById('streaming-mode');
    if (!element) return;
    var options = modeOptionsForProtocol();
    element.innerHTML = '';
    options.forEach(function(value) {
      var option = document.createElement('option');
      option.value = value;
      option.textContent = tKey('wizard.streaming.mode.' + value);
      element.appendChild(option);
    });
    if (preferredValue && options.indexOf(preferredValue) >= 0) {
      element.value = preferredValue;
    } else {
      element.value = options.indexOf('unary') >= 0 ? 'unary' : (options[0] || 'unary');
    }
    updateStreamingTransportOptions();
  }

  function ensureStreamingToolFamilyDefaults(mode) {
    var base = text('tool-name') || 'stream_tool';
    if (mode === 'session') {
      if (!text('streaming-start-tool-name')) set('streaming-start-tool-name', base + '_start');
      if (!text('streaming-poll-tool-name')) set('streaming-poll-tool-name', base + '_poll');
      if (!text('streaming-stop-tool-name')) set('streaming-stop-tool-name', base + '_stop');
    }
    if (mode === 'async_job') {
      if (!text('streaming-start-tool-name')) set('streaming-start-tool-name', base + '_start');
      if (!text('streaming-status-tool-name')) set('streaming-status-tool-name', base + '_status');
      if (!text('streaming-result-tool-name')) set('streaming-result-tool-name', base + '_result');
      if (!text('streaming-cancel-tool-name')) set('streaming-cancel-tool-name', base + '_cancel');
    }
  }

  function updateStreamingConfigVisibility() {
    var mode = selectedMode();
    var card = document.getElementById('wizard-streaming-config-card');
    var help = document.getElementById('streaming-mode-help');
    var toolFamily = document.getElementById('streaming-tool-family-block');
    var asyncRow = document.getElementById('streaming-async-tool-family-row');
    if (!card) return;

    var isUnary = mode === 'unary';
    var isSession = mode === 'session';
    var isAsyncJob = mode === 'async_job';

    [
      'streaming-window-duration-ms',
      'streaming-poll-interval-ms',
      'streaming-upstream-timeout-ms',
      'streaming-idle-timeout-ms',
      'streaming-session-lifetime-ms',
      'streaming-max-items',
      'streaming-max-bytes',
      'streaming-max-field-length',
      'streaming-sampling-rate',
      'streaming-items-path',
      'streaming-summary-path',
      'streaming-done-path',
      'streaming-cursor-path',
      'streaming-status-path',
      'streaming-redacted-paths',
      'streaming-truncate-item-fields',
      'streaming-drop-duplicates'
    ].forEach(function(id) {
      var node = document.getElementById(id);
      if (!node) return;
      var group = node.closest('.form-group') || node.closest('.checkbox-pill');
      if (group) {
        group.hidden = isUnary;
      }
    });

    if (help) {
      help.textContent = isUnary
        ? tKey('wizard.streaming.help.unary')
        : (isSession
          ? tKey('wizard.streaming.help.session')
          : (isAsyncJob
            ? tKey('wizard.streaming.help.async_job')
            : tKey('wizard.streaming.help.window')));
    }

    if (toolFamily) toolFamily.hidden = !(isSession || isAsyncJob);
    if (asyncRow) asyncRow.hidden = !isAsyncJob;

    ensureStreamingToolFamilyDefaults(mode);
  }

  function bindStreamingConfigControls() {
    updateStreamingModeOptions();
    updateStreamingConfigVisibility();

    var mode = document.getElementById('streaming-mode');
    if (mode) {
      mode.addEventListener('change', function() {
        updateStreamingTransportOptions();
        updateStreamingConfigVisibility();
      });
    }
  }

  function serializeStreamingConfig() {
    if (selectedMode() === 'unary') {
      return null;
    }

    var config = {
      mode: selectedMode(),
      transport_behavior: text('streaming-transport-behavior') || 'request_response',
      aggregation_mode: text('streaming-aggregation-mode') || 'summary_plus_samples',
      window_duration_ms: number('streaming-window-duration-ms'),
      poll_interval_ms: number('streaming-poll-interval-ms'),
      upstream_timeout_ms: number('streaming-upstream-timeout-ms'),
      idle_timeout_ms: number('streaming-idle-timeout-ms'),
      max_session_lifetime_ms: number('streaming-session-lifetime-ms'),
      max_items: number('streaming-max-items'),
      max_bytes: number('streaming-max-bytes'),
      max_field_length: number('streaming-max-field-length'),
      sampling_rate: number('streaming-sampling-rate'),
      items_path: text('streaming-items-path') || null,
      summary_path: text('streaming-summary-path') || null,
      done_path: text('streaming-done-path') || null,
      cursor_path: text('streaming-cursor-path') || null,
      status_path: text('streaming-status-path') || null,
      redacted_paths: lines('streaming-redacted-paths'),
      truncate_item_fields: checked('streaming-truncate-item-fields'),
      drop_duplicates: checked('streaming-drop-duplicates'),
      tool_family: {},
    };

    if (config.mode === 'session') {
      config.tool_family.start_tool_name = text('streaming-start-tool-name') || null;
      config.tool_family.poll_tool_name = text('streaming-poll-tool-name') || null;
      config.tool_family.stop_tool_name = text('streaming-stop-tool-name') || null;
    } else if (config.mode === 'async_job') {
      config.tool_family.start_tool_name = text('streaming-start-tool-name') || null;
      config.tool_family.status_tool_name = text('streaming-status-tool-name') || null;
      config.tool_family.result_tool_name = text('streaming-result-tool-name') || null;
      config.tool_family.cancel_tool_name = text('streaming-cancel-tool-name') || null;
    }

    return config;
  }

  function validateStreamingConfig(capabilities) {
    var config = serializeStreamingConfig();
    if (!config) {
      return { valid: true, errors: [] };
    }

    var errors = [];
    var capability = (capabilities || []).find(function(item) {
      return item.protocol === window.wizardProtocol;
    });

    if (capability && Array.isArray(capability.supports_execution_modes)) {
      var supported = capability.supports_execution_modes.map(String);
      if (supported.indexOf(config.mode) === -1) {
        errors.push('Selected execution mode is not supported by the current protocol.');
      }
    }

    if (!config.max_items || config.max_items <= 0) {
      errors.push('Max items must be a positive integer.');
    }

    if (!config.max_bytes || config.max_bytes <= 0) {
      errors.push('Max bytes must be a positive integer.');
    }

    if (config.mode === 'window' && (!config.window_duration_ms || config.window_duration_ms <= 0)) {
      errors.push('Window duration must be set for window mode.');
    }

    if (config.mode === 'session' && (!config.poll_interval_ms || config.poll_interval_ms <= 0)) {
      errors.push('Poll interval must be set for session mode.');
    }

    if (config.mode === 'async_job' && (!config.max_session_lifetime_ms || config.max_session_lifetime_ms <= 0)) {
      errors.push('Session lifetime must be set for async job mode.');
    }

    return {
      valid: errors.length === 0,
      errors: errors,
      config: config,
    };
  }

  window.CrankStreamingForm = {
    selectedStreamingMode: selectedMode,
    bindStreamingConfigControls: bindStreamingConfigControls,
    collectStreamingConfig: serializeStreamingConfig,
    applyStreamingConfig: function(streaming) {
      updateStreamingModeOptions(streaming && streaming.mode ? streaming.mode : 'unary');
      if (!streaming) {
        updateStreamingConfigVisibility();
        return;
      }

      if (streaming.window_duration_ms != null) set('streaming-window-duration-ms', String(streaming.window_duration_ms));
      if (streaming.poll_interval_ms != null) set('streaming-poll-interval-ms', String(streaming.poll_interval_ms));
      if (streaming.upstream_timeout_ms != null) set('streaming-upstream-timeout-ms', String(streaming.upstream_timeout_ms));
      if (streaming.idle_timeout_ms != null) set('streaming-idle-timeout-ms', String(streaming.idle_timeout_ms));
      if (streaming.max_session_lifetime_ms != null) set('streaming-session-lifetime-ms', String(streaming.max_session_lifetime_ms));
      if (streaming.max_items != null) set('streaming-max-items', String(streaming.max_items));
      if (streaming.max_bytes != null) set('streaming-max-bytes', String(streaming.max_bytes));
      if (streaming.max_field_length != null) set('streaming-max-field-length', String(streaming.max_field_length));
      if (streaming.sampling_rate != null) set('streaming-sampling-rate', String(streaming.sampling_rate));
      set('streaming-items-path', streaming.items_path || '');
      set('streaming-summary-path', streaming.summary_path || '');
      set('streaming-done-path', streaming.done_path || '');
      set('streaming-cursor-path', streaming.cursor_path || '');
      set('streaming-status-path', streaming.status_path || '');
      set('streaming-redacted-paths', (streaming.redacted_paths || []).join('\n'));
      var truncate = document.getElementById('streaming-truncate-item-fields');
      if (truncate) truncate.checked = !!streaming.truncate_item_fields;
      var dedupe = document.getElementById('streaming-drop-duplicates');
      if (dedupe) dedupe.checked = !!streaming.drop_duplicates;
      set('streaming-aggregation-mode', streaming.aggregation_mode || 'summary_plus_samples');

      updateStreamingTransportOptions(streaming.transport_behavior);

      var toolFamily = streaming.tool_family || {};
      set('streaming-start-tool-name', toolFamily.start_tool_name || '');
      set('streaming-poll-tool-name', toolFamily.poll_tool_name || '');
      set('streaming-stop-tool-name', toolFamily.stop_tool_name || '');
      set('streaming-status-tool-name', toolFamily.status_tool_name || '');
      set('streaming-result-tool-name', toolFamily.result_tool_name || '');
      set('streaming-cancel-tool-name', toolFamily.cancel_tool_name || '');

      updateStreamingConfigVisibility();
    },
    serializeStreamingConfig: serializeStreamingConfig,
    updateStreamingModeOptions: updateStreamingModeOptions,
    updateStreamingConfigVisibility: updateStreamingConfigVisibility,
    deserializeStreamingConfig: function(streaming) {
      if (typeof window.applyStreamingConfig === 'function') {
        window.applyStreamingConfig(streaming);
      }
    },
    validateStreamingConfig: validateStreamingConfig,
  };
}());
