<!-- #region UrlParser [C:3] [TYPE Component] [SEMANTICS llm,validation,url-parser,dashboard] -->
<!-- @BRIEF URL paste + parse component for Superset dashboard URLs — accepts URL, calls parse endpoint, shows result with Add action. -->
<!-- @RELATION DEPENDS_ON -> [ApiModule] -->
<!-- @RELATION BINDS_TO -> [I18nModule] -->
<!-- @UX_STATE idle -> URL input visible with Parse button -->
<!-- @UX_STATE parsing -> Spinner in button, input disabled -->
<!-- @UX_STATE success -> Green banner with dashboard metadata + Add button -->
<!-- @UX_STATE error -> Red banner with error message -->
<!-- @UX_STATE partial -> Amber banner with warning + Add Anyway button -->
<!-- @UX_FEEDBACK Success/Error banners appear inline below the input -->
<!-- @UX_RECOVERY Edit URL and retry Parse; dismiss banner -->
<script lang="ts">
  /**
   * UrlParser component — paste a Superset dashboard URL, parse it, and emit the result.
   * @prop {(source: {url: string, title: string, filters_count?: number, tabs_count?: number}) => void} onAdd — Called when user clicks Add on a parsed source
   * @prop {string} envId — Environment ID for context
   */
  import { api } from '$lib/api.js';
  import { t } from '$lib/i18n/index.svelte.js';
  import { addToast } from '$lib/toasts.svelte.js';

  let { onAdd = undefined, envId = '' } = $props();

  let /** @type {'idle'|'parsing'|'success'|'error'|'partial'} */ parseState = $state('idle');
  let url = $state('');
  let /** @type {null | {title: string, filters_count?: number, tabs_count?: number, warnings?: string[]}} */ parsedResult = $state(null);
  let errorMsg = $state('');
  let warningMsg = $state('');

  function handleParse() {
    if (!url.trim()) {
      addToast($t.validation?.parse_no_url || 'Please enter a URL', 'warning');
      return;
    }
    if (!envId) {
      addToast($t.validation?.select_environment || 'Select an environment first', 'warning');
      return;
    }

    parseState = 'parsing';
    errorMsg = '';
    warningMsg = '';
    parsedResult = null;

    api.parseValidationUrl(url.trim(), envId)
      .then((result) => {
        if (result.warnings && result.warnings.length > 0) {
          parseState = 'partial';
          warningMsg = result.warnings.join('; ');
          parsedResult = {
            title: result.title || 'Unknown Dashboard',
            filters_count: result.filters_count,
            tabs_count: result.tabs_count,
            warnings: result.warnings,
          };
        } else {
          parseState = 'success';
          parsedResult = {
            title: result.title || 'Unknown Dashboard',
            filters_count: result.filters_count,
            tabs_count: result.tabs_count,
          };
        }
      })
      .catch((err) => {
        parseState = 'error';
        errorMsg = err?.message || ($t.validation?.parse_fetch_error || 'Network error while parsing URL');
        parsedResult = null;
      });
  }

  function handleAdd() {
    if (parsedResult && onAdd) {
      onAdd({
        url: url.trim(),
        title: parsedResult.title,
        filters_count: parsedResult.filters_count,
        tabs_count: parsedResult.tabs_count,
      });
    }
    // Reset after add
    parseState = 'idle';
    url = '';
    parsedResult = null;
    errorMsg = '';
    warningMsg = '';
  }

  function handleDismiss() {
    parseState = 'idle';
    parsedResult = null;
    errorMsg = '';
    warningMsg = '';
  }

  function handleKeydown(e) {
    if (e.key === 'Enter' && parseState !== 'parsing') {
      handleParse();
    }
  }
</script>

<div class="space-y-3">
  <!-- URL Input Row -->
  <div class="flex gap-2">
    <input
      type="url"
      value={url}
      oninput={(e) => { url = /** @type {HTMLInputElement} */(e.target).value; if (parseState === 'error' || parseState === 'success' || parseState === 'partial') handleDismiss(); }}
      onkeydown={handleKeydown}
      placeholder={$t.validation?.url_placeholder || 'Paste Superset dashboard URL...'}
      disabled={parseState === 'parsing'}
      class="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none disabled:bg-gray-50 disabled:cursor-not-allowed"
      aria-label={$t.validation?.url_placeholder || 'Paste Superset dashboard URL...'}
    />
    <button
      onclick={handleParse}
      disabled={parseState === 'parsing' || !url.trim()}
      class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors text-sm font-medium whitespace-nowrap"
    >
      {#if parseState === 'parsing'}
        <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
        </svg>
        {$t.validation?.parsing || 'Parsing...'}
      {:else}
        <svg class="w-4 h-4 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
        </svg>
        {$t.validation?.parse_url || 'Parse'}
      {/if}
    </button>
  </div>

  <!-- Success Banner -->
  {#if parseState === 'success' && parsedResult}
    <div class="flex items-start gap-3 p-3 bg-green-50 border border-green-200 rounded-lg" role="status">
      <div class="flex-shrink-0 mt-0.5">
        <svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
        </svg>
      </div>
      <div class="flex-1 min-w-0">
        <p class="text-sm font-medium text-green-800">{parsedResult.title}</p>
        <p class="text-xs text-green-600 mt-0.5">
          {($t.validation?.parse_success || 'Dashboard: {title}, {filters} filters, {tabs} tabs')
            .replace('{title}', parsedResult.title)
            .replace('{filters}', String(parsedResult.filters_count ?? 0))
            .replace('{tabs}', String(parsedResult.tabs_count ?? 0))}
        </p>
      </div>
      <button
        onclick={handleAdd}
        class="flex-shrink-0 px-3 py-1.5 text-xs font-medium bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors"
      >
        {$t.validation?.add_dashboard || 'Add'}
      </button>
    </div>
  {/if}

  <!-- Partial Recovery Banner -->
  {#if parseState === 'partial' && parsedResult}
    <div class="flex items-start gap-3 p-3 bg-amber-50 border border-amber-200 rounded-lg" role="alert">
      <div class="flex-shrink-0 mt-0.5">
        <svg class="w-5 h-5 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z" />
        </svg>
      </div>
      <div class="flex-1 min-w-0">
        <p class="text-sm font-medium text-amber-800">{parsedResult.title}</p>
        <p class="text-xs text-amber-600 mt-0.5">
          {($t.validation?.parse_partial || 'Partial recovery: {warning}').replace('{warning}', warningMsg)}
        </p>
      </div>
      <button
        onclick={handleAdd}
        class="flex-shrink-0 px-3 py-1.5 text-xs font-medium bg-amber-600 text-white rounded-md hover:bg-amber-700 transition-colors"
      >
        {$t.validation?.add_dashboard || 'Add'}
      </button>
    </div>
  {/if}

  <!-- Error Banner -->
  {#if parseState === 'error'}
    <div class="flex items-start gap-3 p-3 bg-red-50 border border-red-200 rounded-lg" role="alert">
      <div class="flex-shrink-0 mt-0.5">
        <svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
        </svg>
      </div>
      <div class="flex-1 min-w-0">
        <p class="text-sm text-red-700">
          {($t.validation?.parse_error || 'URL parsing failed: {error}').replace('{error}', errorMsg)}
        </p>
      </div>
      <button
        onclick={handleDismiss}
        class="flex-shrink-0 text-xs text-red-600 hover:text-red-800 underline"
      >
        {$t.validation?.cancel || 'Dismiss'}
      </button>
    </div>
  {/if}
</div>
<!-- #endregion UrlParser -->
